Aiuta a visualizzare quale middleware è effettivamente.
(defn middleware [handler]
(fn [request]
;; ...
;; Do something to the request before sending it down the chain.
;; ...
(let [response (handler request)]
;; ...
;; Do something to the response that's coming back up the chain.
;; ...
response)))
Quel giusto per me era praticamente il momento degli a-ha.
Ciò che confonde a prima vista è che il middleware non è applicato alla richiesta, che è ciò a cui stai pensando.
Ricordiamo che un'applicazione Ring è solo una funzione che prende una richiesta e restituisce una risposta (che significa che è un gestore):
((fn [request] {:status 200, ...}) request) ;=> response
Facciamo rimpicciolire un po '. Otteniamo un altro gestore:
((GET "/" [] "Hello") request) ;=> response
Esaminiamo un po 'di più. Troviamo la my-routes
gestore:
(my-routes request) ;=> response
Beh, e se si voleva fare qualcosa prima di inviare la richiesta al gestore di my-routes
? Puoi avvolgerlo con un altro gestore.
((fn [req] (println "Request came in!") (my-routes req)) request) ;=> response
Questo è un po 'difficile da leggere, quindi scoppiamo per chiarezza. Possiamo definire una funzione che restituisce quel gestore. Il middleware è una funzione che accetta un gestore e lo avvolge con un altro gestore. Non restituisce una risposta. Restituisce un gestore che può restituire una risposta.
(defn println-middleware [wrapped-func]
(fn [req]
(println "Request came in!")
(wrapped-func req)))
((println-middleware my-route) request) ;=> response
E se abbiamo bisogno di fare qualcosa prima ancora println-middleware
riceve la richiesta, quindi siamo in grado di avvolgere di nuovo:
((outer-middleware (println-middleware my-routes)) request) ;=> response
La chiave è che my-routes
, proprio come il vostro my-handler
, è l'unico nome funzione che in realtà accetta la richiesta come argomento.
Una dimostrazione finale:
(handler3 (handler2 (handler1 request))) ;=> response
((middleware1 (middleware2 (middleware3 handler1))) request) ;=> response
scrivo così tanto perché posso simpatizzare. Ma torna al mio primo esempio di middleware
e speriamo che abbia più senso.