1
votes

I'm using compojure-api, and I'm looking for a function that, given my api route structure thingie and a request, returns the Route record (or :name) for that request, without applying its handler.

I've been able to find kind of the inverse of what I'm looking for in compojure.api.routes/path-for, which, given a :name, returns the path for the corresponding route. In the same namespace there are also functions like get-routes which seem promising, but I've yet to find exactly what I'm looking for.

In other words, given this simple example

(defapi my-api
  (context "/" []
    (GET "/myroute" request
      :name :my-get
      (ok))
    (POST "/myroute" request
      :name :my-post
      (ok))))

I'm looking for a function foo that works like this

(foo my-api (mock/request :get "/myroute"))
;; => #Route{:path "/myroute", :method :get, :info {:name :my-get, :public {:x-name :my-get}}}
;; or
;; => :my-get

Any ideas?

1

1 Answers

3
votes

my-api is defined as a Route Record, so you can evaluate it at the repl to see what it looks like:

#Route{:info {:coercion :schema},
       :childs [#Route{:childs [#Route{:path "/",
                                       :info {:static-context? true},
                                       :childs [#Route{:path "/myroute",
                                                       :method :get,
                                                       :info {:name :my-get, :public {:x-name :my-get}}}
                                                #Route{:path "/myroute",
                                                       :method :post,
                                                       :info {:name :my-post, :public {:x-name :my-post}}}]}]}]}

There are helpers in compojure.api.routes to transform the structure:

(require '[compojure.api.routes :as routes])

(routes/get-routes my-api)
; [["/myroute" :get {:coercion :schema, :static-context? true, :name :my-get, :public {:x-name :my-get}}]
;  ["/myroute" :post {:coercion :schema, :static-context? true, :name :my-post, :public {:x-name :my-post}}]]

, which effectively flattens the route tree while retaining the order. For reverse routing there is:

(-> my-api
    routes/get-routes
    routes/route-lookup-table)
; {:my-get {"/myroute" {:method :get}}
;  :my-post {"/myroute" {:method :post}}}

More utilities can be added if needed.

Hope this helps.