This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-09-04
Channels
- # architecture (9)
- # babashka (33)
- # beginners (53)
- # biff (3)
- # cljdoc (11)
- # clojure (8)
- # clojure-austria (2)
- # clojure-dev (9)
- # clojure-europe (64)
- # clojure-nl (2)
- # clojure-norway (49)
- # clojure-sweden (4)
- # clojure-uk (4)
- # clojurescript (16)
- # cursive (14)
- # datahike (31)
- # datalevin (6)
- # datascript (9)
- # events (1)
- # fulcro (4)
- # honeysql (8)
- # hyperfiddle (116)
- # introduce-yourself (1)
- # kaocha (2)
- # malli (13)
- # nyc (2)
- # off-topic (4)
- # polylith (5)
- # portal (1)
- # reagent (1)
- # reitit (18)
- # releases (1)
- # spacemacs (6)
Hi, I’m trying to add a middleware to an existing router and struggling to understand the order of execution
(defn- create-router
"creates a reitit router and validates its structure"
[routes]
(reitit-ring/router
routes
{:data {:muuntaja (-> muuntaja/default-options
(update :formats select-keys ["application/json"])
muuntaja/create)
:middleware [some-middlewares-that-do-stuff-on-headers-and-such
middleware-I-want-to-add-that-does-stuff-on-body-of-request]}}))
Right now it seems to me that muuntaja is executed after all of the middleware the I pass to middleware
. Am I correct?
How is the order of execution of the middleware determined (`:middleware` and :muujata
)?
The middleware I want to add should take place after muuntaja. How can I do that?Currently I don't see any middleware related to muuntaja at all, but iirc in reitit the order of middlewares in the vector is top down, e.g. if both mws do something before a handler is invoked, the order of execution will be the same as the order of the vector
So muuntaja isn’t a middleware because it doesn’t take a handler, it’s just a transformer? I want to to add a middleware that assocs a field to the body, so I need it to be executed after muuntaja. Should I take muuntaja and turn it into a middleware?
Let's take the example from reitit's repo:
;; query-params & form-params
parameters/parameters-middleware ;; happens before everything, parses query and form params 1
;; content-negotiation
muuntaja/format-negotiate-middleware ;; format negotiation, adds metadata to the request regarding formats 2
;; encoding response body
muuntaja/format-response-middleware ;; happens after handler, formats response according to format negotiation from before 7
;; exception handling
exception/exception-middleware ;; handle exceptions 3 (wraps everything after it)
;; decoding request body
muuntaja/format-request-middleware ;; apply format negotiation from before to request 4
;; coercing response bodys
coercion/coerce-response-middleware ;; apply coercion to parameters - query, body, form, headers 5
;; coercing request parameters
coercion/coerce-request-middleware ;; apply coercion to response - body, headers 6
I added comments and the order in which these mw's happenSo how did it work without any of these before?
I don't know what else your code was doing, you elided some details and other middlewares which might have been applied
Anyone ever attempted to create proper error-messages from coercion-errors? Is there a lib somewhere? The returned error-spec when using clojure-spec is pretty terrible to parse. Does anyone have a hint?
using malli and the exception interceptor like https://github.com/bob-cd/bob/blob/main/apiserver/src/apiserver/server.clj#L45 before the coercion interceptors gets me pretty far with decent "humanised" errors
https://github.com/dharrigan/startrek/blob/master/src/startrek/shared/middleware/exceptions.clj
then I use resolve-message
to pick an i18n (and templated) message from my resources
Thanks @U11EL3P9U, looking into it. encode-error
seems an interesting little helper.