reitit

https://cljdoc.org/d/metosin/reitit/ https://github.com/metosin/reitit/
flowthing 2020-12-15T11:34:01.410700Z

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?

dharrigan 2020-12-15T12:19:56.411200Z

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

dharrigan 2020-12-15T12:20:40.411900Z

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

scythx 2020-12-15T12:21:07.412Z

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?})}}}]

flowthing 2020-12-15T12:26:16.412300Z

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

Dave Russell 2020-12-15T13:24:41.412500Z

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}
...

flowthing 2020-12-15T13:26:01.412700Z

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

Steven Deobald 2020-12-15T20:36:43.413800Z

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 Deobald 2020-12-15T20:38:52.416Z

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 Deobald 2020-12-15T21:00:39.417700Z

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 Deobald 2020-12-15T21:19:15.419500Z

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. 😉 )