Fork me on GitHub
#reitit
<
2021-07-28
>
Zaymon02:07:04

Hey Reitit people, is there a way to understand which order middlewares are supposed to be specified in? I’m not sure how to think about the problem since I’ve never done it before. My middleware currently looks like this:

{:muuntaja formats/instance
    :coercion malli-coercer
    :swagger {:id ::api}
    :middleware [(make-request-logger env)

                 ;; Cors
                 (fn [handler]
                   (wrap-cors
                    handler
                    :access-control-allow-origin [#""
                                                  #""]
                    :access-control-allow-methods [:get :put :patch :post :options :delete]))

                 ;; Exception Middleware
                 exception/exception-middleware

                 ;; Coercion exception handling
                 ring-coercion/coerce-exceptions-middleware

                 ;;  query-params & form-params
                 parameters/parameters-middleware

                 ;; content-negotiation
                 muuntaja/format-negotiate-middleware

                 ;; encoding response body
                 muuntaja/format-response-middleware
                 ;; decoding request body
                 muuntaja/format-request-middleware

                 ;; coercing request parameters
                 ring-coercion/coerce-request-middleware
                 ;; coercing response bodys
                 ring-coercion/coerce-response-middleware

                 ;; multipart
                 multipart/multipart-middleware]

    :compile coercion/compile-request-coercers
    :exception pretty/exception}
Request coercion exceptions end up coming through like this:
ERROR io.undertow.request - UT005071: Undertow request failed HttpServerExchange{ POST /api/letters/} 
java.lang.UnsupportedOperationException: Body class not supported: class clojure.lang.PersistentArrayMap
....
And a lot of other exceptions come through to the front-end as CORS errors instead of getting nicer messages. If anyone can spot what’s wrong here, or help me to start understanding how middleware are supposed to be arranged that would be very helpful!

Zaymon02:07:40

Looks like I worked through my problems. Funny how composing a question in enough detail leads your brain to understanding what you’re missing. I think fundamentally still haven’t quite internalised in which order the middleware wraps the next. How does the list of middlewares get processed to create a chain of functions? Is the first function in the list, the innermost function in the middleware chain? And each consecutive middleware wraps around that? Or is it the reverse?

Eg.
[first second third] -> (third (second (first ..)))?

Or is it this way round:
(first (second (third)))?

Tuomas08:07:53

There are good examples at https://cljdoc.org/d/metosin/reitit/0.5.13/doc/ring/data-driven-middleware the left most is called first, so it gets to modify the request first and the response last

metal 3
Zaymon22:07:25

Thanks, that clears it up! @UH9091BLY

Itay11:07:22

Hi, Two days ago I opened this issue regarding Malli response coercion not working: https://github.com/metosin/reitit/issues/498 Can someone help? Does anyone have a working example that coerces anything out of the response body? My current conclusion is that this does not work at all, in any scenario, but I would love it if someone could prove me wrong. Thanks!

😮 3