I've seen this done a couple of ways. The first is using middleware that injects the state as a new key in the request map. For instance:
(defroutes main-routes
(GET "/api/fu" [:as request]
(rest-of-the-app (:app-state request))))
(defn app-middleware [f state]
(fn [request]
(f (assoc request :app-state state))))
(def app
(-> main-routes
(app-middleware (create-app-state))
handler/api))
The other approach is to replace the call to defroutes
, which behind the scenes will create a handler and assign it to a var, with a function that will accept some state and then create the routes, injecting the state as parameters to function calls within the route definitions:
(defn app-routes [the-state]
(compojure.core/routes
(GET "/api/fu" [] (rest-of-the-app the-state))))
(def app
(-> (create-app-state)
app-routes
api/handler))
Given a choice, I'd probably go with the second approach.