I have an app that generates keys based for specific datastores. If there are 7 such routes and 5 apps, there would be a total of 35 routes in my event.clj (or, if split out, 7/file in 5 files). I would like to do the following dynamically:
(defnested "/:app-name"
(defpage "/generate/event" {:keys [app-name event-name time] :as key-map}
(response/json
{:key (key-model/build-key :event key-map)}))
(defpage "/generate/event/unread" {:keys [app-name event-name] :as key-map}
(response/json
{:key (key-model/build-key :unread-for-event key-map)}))
)
That way I can write each route once and then pass around the app-name (instead of passing it in the query params, which works but isn't very RESTful.
BONUS
How can I dynamically call a namespace so that key-model/build-key
becomes a call to redis-model/build-key
or riak-model/build-key
based on the app name?
Not sure if I understand the question but isn't this what your are looking for:
(defpage "/:app-name/generate/event" {:keys [app-name event-name time] :as key-map}
(response/json
{:key (key-model/build-key :event key-map)}))
(defpage "/:app-name/generate/event/unread" {:keys [app-name event-name] :as key-map}
(response/json
{:key (key-model/build-key :unread-for-event key-map)}))
BONUS
I will also go for a simple solution of having a map with the funcitons to generate the keys, something like:
(def key-gen {"redis" redis-model/build-key
"riak" riak/build-key})
(response/json
{:key ((get key-gen app-name) :event key-map)})
If you really want to dynamically find the build-key function, you can do something like:
(defn build-key [app-name]
(let [the-ns (symbol (str app-name "-model"))]
(require the-ns)
(ns-resolve the-ns 'build-key)))