Fork me on GitHub
#reitit
<
2020-12-15
>
flowthing11:12:01

I'm trying to use spec coercion with query parameters. I have a route like this:

["/foo"
 {:get {:handler my-handler
        :parameters {:query {:download boolean?}}}}]
However, if I do that, the download query param is mandatory. If I don't pass it, the route returns an error. Is there any way to make it optional?

scythx12:12:07

You might want use data-spec maybe function for this. https://cljdoc.org/d/metosin/spec-tools/0.10.4/api/spec-tools.data-spec#maybe In your case it should be like this:

;; import spec-tools.data-spec :as ds for ;; your namespace

["/foo"
 {:get {:handler my-handler
        :parameters {:query (ds/maybe {:download boolean?})}}}]

flowthing12:12:16

maybe didn't work, but your tip led me to {(data-spec/opt :download) boolean?}, which does work. Thanks!

Dave Russell13:12:41

Another way to handle this with standard specs is to spec all of query-params as a map, rather than using specs for each individual key:

(s/def ::download boolean?)
(s/def ::query-params (s/keys :opt-un [::download]))
...
   :parameters {:query ::query-params}
...

flowthing13:12:01

Thanks! I didn't realize you could do that here. :thumbsup::skin-tone-2:

dharrigan12:12:56

if you are using malli, you could define a spec like this:

dharrigan12:12:40

[:map [:download {:optional true} boolean?]]

Steven Deobald20:12:43

I’m looking at https://github.com/metosin/reitit/blob/master/doc/ring/RESTful_form_methods.md (which is a very simple piece of documentation I’m wildly grateful for, btw) and wondering about these comments: ;; needed to have :form-params / :multipart-params in the request map

Steven Deobald20:12:52

I’m using the regular ring middleware for form-params and multipart-params at the moment and it looks like the reitit middleware handler for form-params, at least, is just a pass-through wrapper. But the multipart-params reitit wrapper is doing a few things (mostly swagger, from the looks of it, which would agree with the docs at https://cljdoc.org/d/metosin/reitit/0.5.5/doc/ring/default-middleware …but is it advisable to switch from the vanilla ring.middleware to reitit.ring.middleware in both these cases?

Steven Deobald21:12:39

It would appear, due to the ordering of middleware processing, that it needs to be the reitit.ring.middleware used to wrap _method fakes this way? (At least as long as the wrap-hidden-method itself is reitit middleware?)

Steven Deobald21:12:15

The data-oriented approach for middleware (a chain of maps in a vector instead of a reverse list of fns in a threading macro) really makes complete sense to me, the more I’m looking at this. Do folks who’ve fully committed to reitit just wrap all the standard ring middleware in maps to keep it all in one place, usually? (I’m willing to do that but I’d like to make sure that’s a sane approach before I do. 😉 )