Hi,
I'm playing with the idea of using clojure.spec to make an API backwards
compatible by using conform and unform to transform data from the old
version format to a new format version. Below is an example of this in code:
Say we have API change that involves changing the name of a nested key:
(do
;; Old api
(s/def :api.v0.input.nested/label keyword?)
(s/def :api.v0.input/nested (s/keys :req-un [:api.v0.input.nested/label]))
(s/def :api.v0/input (s/keys :req-un [:api.v0.input/nested]))
;; New api
(s/def :api.v1.input.nested/key keyword?)
(s/def :api.v1.input/nested (s/keys :req-un [:api.v1.input.nested/key]))
(s/def :api.v1/input (s/keys :req-un [:api.v1.input/nested]))
;; Migration specs
(s/def :api.v0-v1.migration.input/nested (s/conformer (fn [_] (throw
(ex-info "Don't use as conformer" {})))
(fn [x]
(clojure.set/rename-keys x {:label :key}))))
(s/def :api.v0-v1.migration/input (s/conformer (fn [x]
(s/conform :api.v1/input
x))
(fn [x]
(s/unform (s/keys
:req-un [:api.v0-v1.migration.input/nested]) x))))
;; Changes {:nested {:label :hi}} to {:nested {:key :hi}}
(s/unform :api.v0-v1.migration/input {:nested {:label :hi}}))
So this kind of works, but I wonder whether there is an easier way or if
I'm thinking about this the wrong way. I was hoping there would be
something like with-unformer (like with-gen) that allows me to change the
unforming action for a specific key without having to copy most of the old
spec.
Any suggestions or advise is appreciated.
Thanks,
Jeroen
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.