ring-swagger

ring-swagger & compojure-api
ikitommi 2018-06-25T05:19:07.000048Z

@andreasp1994 compojure-api is built with macros (like Compojure), generating the source code. The :middleware is resolved at (macro) compilation time, so it can’t see runtime bound things like mw variable. I believe the evaluation could be delayed so that would work, feel free to create an issue out of that.

Andreasp1994 2018-06-25T13:22:00.000107Z

@ikitommi Thanks for the explanation! 🙂

Andreasp1994 2018-06-25T13:23:54.000272Z

In that case.. Do you have any suggestions for applying the authentication middleware conditionally on some routes?

ikitommi 2018-06-25T13:56:28.000811Z

@andreasp1994 you can put code in the :middleware vector.

ikitommi 2018-06-25T13:58:22.000718Z

nils are stripped away, so :middleware [(if false auth-mw)] doesn’t mount anything

ikitommi 2018-06-25T13:59:18.000205Z

there is compojure.api.middleware/compose-middleware function that gets called.

ikitommi 2018-06-25T14:01:33.000114Z

are you thinking of applying mw based on request? or just having a code that selects the suitable mw at api creation time?

Andreasp1994 2018-06-25T14:03:22.000223Z

Basically just having a code that selects suitable mw at api creation time

ikitommi 2018-06-25T14:03:46.000735Z

In the end, it’s not very easy to know with Compojure what happens when - there are at least three stages: 1) compile-time (e.g. the macros get expanded) 2) creation-time (static parts of the routing tree are created - most of the middleware assembly should happen here) 3) request-time - Compojure is a dynamic routing lib and Some things happen at request-time. Fiddling with mw-chain here has a cost (if performance is a factor, usually not)

ikitommi 2018-06-25T14:03:52.000799Z

ok.

Andreasp1994 2018-06-25T14:04:23.000742Z

Thanks for letting me know. I really appreciate your help! Thank you! 🙂

ikitommi 2018-06-25T14:04:41.000688Z

np!

ikitommi 2018-06-25T14:07:31.000473Z

here’s an example:

(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}]}]}]}]}

ikitommi 2018-06-25T14:07:51.000916Z

… all routes are created at creation time (marked with :static-context? true

ikitommi 2018-06-25T14:08:03.000080Z

(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}]}]}]}]}

ikitommi 2018-06-25T14:08:55.000063Z

here all routes are re-created at request-time and the data q is passed via a closure into the subroutes.

ikitommi 2018-06-25T14:10:31.000137Z

the perf is ok in both cases (thanks to precompiled everything), but the first one is still faster.

Andreasp1994 2018-06-25T14:42:12.000018Z

I get you! Thanks for the example! 😉