How do I bind a dynamic variable in compojure? Please see my example below, here the request-id is a unique uuid which is generate for each api request. I would like to be able to access this request-id in subsequent methods for logging etc. I have tried using the binding function, but am still not able to access request-id in some-page/some-method
.
handler.clj
(ns some_app.handler
(:require
[compojure.api.sweet :refer :all]
[compojure.route :as route]
[some_api.some_page :as some-page]))
(def ^:dynamic *request-id*
nil)
(defn ^:private generate-request-id []
(str (java.util.UUID/randomUUID)))
(def app
(binding [*request-id* (generate-request-id)]
(api
(context "/api" [] (GET "/some-page" [] (some-page/some-method))))))
some-page.clj
(ns some_app.some_page
(:require
[clojure.tools.logging :as log]))
(def some-method []
(log/info {:request-id *request-id*}))
The call to binding here is in the wrong place. The binding should be in effect when the request is processed, not when the app/api is being constructed.
You want to have some middleware to do this:
(defn with-request-id
[f]
(fn [request]
(binding [*request-id* (generate-request-id)]
(f request)))
(def app
(with-request-id
(api ... ))
See also Ring Concepts