spec key aliasing or different specs for same keyword

218 views
Skip to first unread message

Jonathon McKitrick

unread,
Dec 28, 2017, 11:28:18 AM12/28/17
to Clojure
I have one spec question covering two scenarios.

1. Suppose I want to spec a payload from a third-party API that has the keyword ':resultCount' in it. Does that mean my specs for that item must have the same name?

2. Supposed I have a few payloads from that API and each has a keyword ':result' but the spec for each will be different. Other than using an entirely different namespace, how can I map the :result keyword to different specs?

Thanks!

adrian...@mail.yu.edu

unread,
Dec 28, 2017, 12:26:59 PM12/28/17
to Clojure
Avoiding global name collision is the reason why specs are named with namespace-qualified keywords. I am confused by your last sentence though. Do you mean Clojure namespaces or the namespace component of the keyword itself? There is no requirement in clojure.spec that the namespace of the specs you def be coupled to the Clojure namespace they happen to be defined in. If you are actually asking about how to write specs for unqualified keys in a map there is a built-in facility to do that as well: clojure.spec.alpha/keys has a :req-un and :opt-un argument.

Jonathon McKitrick

unread,
Dec 28, 2017, 1:09:57 PM12/28/17
to Clojure
Yes, the namespacing is great, so I have no issue with that. I would just rather use snake-case in Clojure than camel-case. Since the payload has 'resultCount' I'd like to map that to a spec named result-count instead.

I think I figured out part of the answer:

(s/def :my/result int?)
(s/def :your/result pos-int?)
(s/def ::test-spec-1 (s/keys :req-un [:my/result]))
(s/def ::test-spec-2 (s/keys :req-un [:your/result]))

I see here that I can have an unqualified keyword as part of a qualified spec name. I think that's what I want.

Gary Verhaegen

unread,
Dec 29, 2017, 7:48:20 AM12/29/17
to clo...@googlegroups.com
You could always extract specific keys from the payload and validate that, something like:

(GET "/..." req
  (let [b (:body req)
        data {:my/result (:resultCount b)
              :my/other-key (get-in b [:some :path])}]
    (my-business-logic data)))

i.e. spec what your code (my-business-logic here) expects, not the API call itself.

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+unsubscribe@googlegroups.com
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 clojure+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages