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?if you are using malli, you could define a spec like this:
[:map [:download {:optional true} boolean?]]
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?})}}}]
maybe
didn't work, but your tip led me to {(data-spec/opt :download) boolean?}
, which does work. Thanks!
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}
...
Thanks! I didn't realize you could do that here. :thumbsup::skin-tone-2:
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
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?
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?)
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. 😉 )