-
Notifications
You must be signed in to change notification settings - Fork 149
Contexts
Compojure is a dynamic routing library: one can generate easily new routes at request-time. Good example of this is the context
macro. With normal Compojure, the body of the context
is re-evaluated with each request. This is good as it enables new routes to be added on fly, based on request. This is (bit) bad for performance as the child route trees are re-evaluated per each request.
Compojure-api does things bit differently. context
is static by default and automatically transformed into dynamic version if the child routes close over any request-bound data in the parent context
s. For example, adding a :query-params [q :- s/Str
annotation into a context
dynamic as the q
is request-bound and is visible to the child routes. One can also mark routes with :dynamic true
to force the request-based child trees.
Let's play in the repl.
Marked in the compiled routes with {:static-context? true}
.
(require '[compojure.api.sweet :refer :all])
(require '[ring.util.http-response :refer :all])
(api
(context "/api" []
(context "/ipa" []
(GET "/drink" []
(ok {:was "good"})))))
;#Route{:info {:coercion :schema},
; :childs [#Route{:childs [#Route{:path "/api",
; :info {:static-context? true},
; :childs [#Route{:path "/ipa",
; :info {:static-context? true},
; :childs [#Route{:path "/drink", :method :get}]}]}]}]}
q
is request-bound and makes the whole subtree dynamic.
(api
(context "/api" []
:query-params [q :- String]
(context "/ipa" []
(GET "/drink" []
(ok {:was "good"})))))
;#Route{:info {:coercion :schema},
; :childs [#Route{:childs [#Route{:path "/api",
; :info {:public {:parameters {:query {Keyword Any, :q java.lang.String}}}},
; :childs [#Route{:path "/ipa",
; :info {:static-context? true},
; :childs [#Route{:path "/drink", :method :get}]}]}]}]}
Performance.
Mostly it doesn't matter, but sometimes it does.