Fork me on GitHub
#ring-swagger
<
2018-06-25
>
ikitommi05:06:07

@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.

Andreasp199413:06:00

@ikitommi Thanks for the explanation! 🙂

Andreasp199413:06:54

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

ikitommi13:06:28

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

ikitommi13:06:22

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

ikitommi13:06:18

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

ikitommi14:06:33

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

Andreasp199414:06:22

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

ikitommi14:06:46

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)

Andreasp199414:06:23

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

ikitommi14:06:31

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

ikitommi14:06:51

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

ikitommi14:06:03

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

ikitommi14:06:55

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

ikitommi14:06:31

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

Andreasp199414:06:12

I get you! Thanks for the example! 😉