JSON is a common data format, especially when interfacing with non-Clojure systems. All keys in JSON objects are strings (not keywords, as is common in Clojure).
It is desirable to be able to validate incoming JSON data and provide helpful error messages when data is poorly formed. Spec is an excellent tool for both, but s/keys
only works with keyword keys.
It would be useful to be able to specify string keys, for instance, given some JSON data like
{"city" "Denver" "state" "CO"}
I would like to write a spec like:
(s/def :location/city string?)
(s/def :location/state string?)
(s/keys :req-str [:location/city :location/state])
where :req-str
is like :req
and :req-un-str
would be like :req-un
. The specs would still be fully-qualified keywords.
The current workaround:
- Convert string keys to keyword keys using
clojure.walk/keywordize-keys
- Validate with spec
- If there are problems, map over the problems and use
stringify-keys
on each val
- Format the problems appropriately (basically, reproduce the formatting of
explain
).
This workaround is not particularly difficult, but since I suspect working with JSON is a common case, it may be useful to support this use case more directly.