Fork me on GitHub

@stevep I can tell you what we're doing in production with clojure.spec at World Singles as far as REST APIs are concerned: we have a spec for each handler (i.e., each API endpoint) and the general pattern is roughly:

(let [params (s/conform ::this-api-spec (:params req))]
  (if (s/invalid? params)
    (error-response (s/explain-data ::this-api-spec (:params req)))
    (normal-process params)))


(how-)do you prevent un-spec-ed keys to propagate further down the normal-process?


@U1DLD0WNR In keeping with Clojure's open-for-extension approach, normal-process will just ignore keys it doesn't care about. Similarly, if I only spec certain keys, others don't get checked -- so the constraints are open.


We have that wrapped up in a macro to reduce boilerplate but that's the essence of it. The error-response function decodes the spec failure based on a set of heuristics and "expected" failure points so we can return documented error codes and localized messages to the client.


We only instrument functions in our dev/test cycle, not in release code. We also have specific "tests" that run clojure.spec.test/check on certain functions.


The argument against just relying on instrument to check arguments is that you want better error messages than spec failures for your clients!


Can I modify to a spec after I’ve defined it? My use case is to add the :fn argument for an fdef but only when I run my tests.


@vikeri why can't you just add it anyway? instrument doesn't run the :fn and :ret bits by default anyway


i use orchestra.spec.test/instrument to do this


@conan I also use orchestra and it runs the :fn by default so that’s why I have that issue


ah, can you swap out which you use in different circumstances? so you can switch on/off the :fn execution


i think you can just call clojure.spec/fdef again fine, and it'll update the spec registry with whatever you give it

Alex Miller (Clojure team)12:01:16

You can specify an alternate spec to use with instrument