-
Notifications
You must be signed in to change notification settings - Fork 256
Middleware
Adding middleware to routes (routes basically being a Ring handler function):
(def routes-without-middleware
(context "/user/:user-id" [user-id]
(GET "/profile" [] ...)
(GET "/posts" [] ...)))
Regardless of it being in a context
or not:
(defroutes routes-without-middleware
(GET "/user/:user-id/profile" [user-id] ...)
(GET "/user/:user-id/posts" [user-id] ...))
Is basically just wrapping it:
(def routes-with-middleware
(wrap-some-middleware routes-without-middleware option1 option2))
There is a catch, but middleware can be wrapped midway through the route definitions:
(defroutes my-routes
(GET "/foo" [] ...)
(-> (GET "/bar" [] ...)
(wrap-some-middleware {:some-option 123}))
(GET "/baz" [] ...)
(route/not-found "<h1>Not found</h1>"))
Regardless of it wrapping a context
or not:
(defroutes my-routes
(GET "/foo" [] ...)
(-> (context "/my-context"
(GET "/bar1" [] ...)
(GET "/bar2" [] ...))
(wrap-some-middleware {:some-option 123}))
(GET "/baz [] ...)
(route/not-found "<h1>Not found</h1>"))
The catch is that wrap-some-middleware
isn't applied until a request is being tried matched against the routes it's wrapping.
This means GET /foo
always goes free, while every subsequent route (including GET /baz
and the not-found
fallback) always gets the middleware applied.
What you are most likely looking for is wrap-routes
.
(defroutes my-routes
(GET "/foo" [] ...)
(-> (GET "/bar" [] ...)
(wrap-routes wrap-some-middleware {:some-option 123}))
(GET "/baz" [] ...))
Which applies the middleware only if the route matches (i.e. GET /bar
). Routes after (like GET /baz
) isn't affected by the middleware.
The same applies when using context
:
(defroutes my-routes
(GET "/foo" [] ...)
(-> (context "/my-context"
(GET "/bar1" [] ...)
(GET "/bar2" [] ...))
(wrap- wrap-some-middleware {:some-option 123}))
(GET "/baz [] ...))
Again the GET /baz
route isn't affected by the middleware applied to the context /my-context
.
Oftentimes multiple middleware are wanted and using routes-without-middleware
from the top it would look like:
(def routes-with-multiple-middleware
(->
routes-without-middleware
(wrap-some-middleware option1 option2)
(wrap-some-other-middleware)))
Dealing with middleware that is only desired on specific routes or contexts:
(defroutes my-routes
(GET "/foo" [] ...)
(-> (context "/my-context"
(GET "/bar1" [] ...)
(GET "/bar2" [] ...))
(wrap-routes wrap-some-middleware {:some-option 123})
(wrap-routes wrap-some-other-middleware))
(GET "/baz [] ...))