reitit/doc/ring/transforming_middleware_chain.md
Alexander Kiel a19849fe58 Make Map Destructuring of Namespaced Keys more Beautiful
It's possible to put the :keys keyword in the namespace of the keys one likes to
destructure. With that one can use symbols in the vector again. One advantage of
having symbols is, that Cursive grays them out if not used. I found two
occurrences of unused destructured keys.
2019-07-13 17:02:41 +03:00

2.1 KiB

Transforming the Middleware Chain

There is an extra option in ring-router (actually, in the underlying middleware-router): :reitit.middleware/transform to transform the middleware chain per endpoint. Value should be a function or a vector of functions that get a vector of compiled middleware and should return a new vector of middleware.

Example Application

(require '[reitit.ring :as ring])
(require '[reitit.middleware :as middleware])

(defn wrap [handler id]
  (fn [request]
    (handler (update request ::acc (fnil conj []) id))))

(defn handler [{::keys [acc]}]
  {:status 200, :body (conj acc :handler)})

(def app
  (ring/ring-handler
    (ring/router
      ["/api" {:middleware [[wrap 1] [wrap 2]]}
       ["/ping" {:get {:middleware [[wrap 3]]
                       :handler handler}}]])))

(app {:request-method :get, :uri "/api/ping"})
; {:status 200, :body [1 2 3 :handler]}

Reversing the Middleware Chain

(def app
  (ring/ring-handler
    (ring/router
      ["/api" {:middleware [[wrap 1] [wrap 2]]}
       ["/ping" {:get {:middleware [[wrap 3]]
                       :handler handler}}]]
      {::middleware/transform reverse})))

(app {:request-method :get, :uri "/api/ping"})
; {:status 200, :body [3 2 1 :handler]}

Interleaving Middleware

(def app
  (ring/ring-handler
    (ring/router
      ["/api" {:middleware [[wrap 1] [wrap 2]]}
       ["/ping" {:get {:middleware [[wrap 3]]
                       :handler handler}}]]
      {::middleware/transform #(interleave % (repeat [wrap :debug]))})))

(app {:request-method :get, :uri "/api/ping"})
; {:status 200, :body [1 :debug 2 :debug 3 :debug :handler]}

Printing Request Diffs

[metosin/reitit-middleware "0.3.9"]

Using reitit.ring.middleware.dev/print-request-diffs transformation, the request diffs between each middleware are printed out to the console. To use it, add the following router option:

:reitit.middleware/transform reitit.ring.middleware.dev/print-request-diffs

Sample output:

Ring Request Diff