This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-12-07
Channels
- # adventofcode (94)
- # babashka (29)
- # babashka-sci-dev (2)
- # beginners (103)
- # calva (15)
- # cider (17)
- # clj-kondo (62)
- # cljsrn (24)
- # clojars (13)
- # clojure (97)
- # clojure-belgium (3)
- # clojure-berlin (3)
- # clojure-czech (1)
- # clojure-europe (68)
- # clojure-nl (1)
- # clojure-norway (3)
- # clojure-seattle (3)
- # clojure-uk (1)
- # clojurescript (7)
- # community-development (29)
- # conjure (2)
- # cursive (14)
- # data-science (15)
- # emacs (3)
- # graphql (10)
- # gratitude (1)
- # holy-lambda (32)
- # hoplon (21)
- # hyperfiddle (2)
- # jobs (2)
- # joyride (36)
- # lsp (4)
- # meander (13)
- # off-topic (203)
- # pathom (3)
- # polylith (6)
- # re-frame (4)
- # reagent (1)
- # reitit (28)
- # releases (1)
- # shadow-cljs (16)
- # slack-help (2)
- # sql (27)
- # vim (2)
Iirc, reitit does not support per-method middleware How much of an effort would you estimate it would be? Is there interest in such a feature?
Do you mean this?
(require '[reitit.ring :as ring])
(let [handler (ring/ring-handler (ring/router ["/ping" {:get {:middleware [(fn [handler]
(fn [request]
{:status 400}
))]
:handler (fn [_] {:status 200})}
:post {:middleware [(fn [handler]
(fn [request]
{:status 500}
))]
:handler (fn [_] {:status 200})}}]))]
(handler {:request-method :get
:uri "/ping"})
(handler {:request-method :post
:uri "/ping"}))
Here it does 🙂
I don’t know about the order (by heart), but it will be mixed
Not in terms of order, I mean, I want to provide a compile middleware that will operate per-method. Is that possible?
I think i’m using it that way, but now I have trouble making a proper example
ok I was missing your compile requirement. Need to find a good compile example first. Do you have one?
@UK0810AQ2 I think it works, but Im probably missing something about the compiling
(let [wrap-label
{:compile (fn [{:keys [my-data]} _]
(fn [handler]
(fn [request]
(update (handler request)
:middleware (fnil conj []) my-data))))}
handler (fn [_] {:status 200})
api (ring/ring-handler (ring/router ["/ping" {:my-data :intermediate
:middleware [wrap-label]
:get {:my-data :get
:middleware [wrap-label]
:handler handler}
:post {:my-data :post
:middleware [wrap-label]
:handler handler}}]
{:data {:my-data :global
:middleware [wrap-label]}}))]
(api {:request-method :get
:uri "/ping"})
(api {:request-method :post
:uri "/ping"})
)
I think the middleware needs to be unique
ok maybe you are right and the compiled version doesn’t work (as expected) when combined :man-shrugging:
This one works
(let [wrap-label0
{:compile (fn [{my-data :my-data0} _]
(fn [handler]
(fn [request]
(update (handler request)
:middleware (fnil conj []) my-data))))}
wrap-label1
{:compile (fn [{my-data :my-data1} _]
(fn [handler]
(fn [request]
(update (handler request)
:middleware (fnil conj []) my-data))))}
wrap-label2
{:compile (fn [{my-data :my-data2} _]
(fn [handler]
(fn [request]
(update (handler request)
:middleware (fnil conj []) my-data))))}
handler (fn [_] {:status 200})
api (ring/ring-handler (ring/router ["/ping" {:my-data1 :intermediate
:middleware [wrap-label1]
:get {:my-data2 :get
:middleware [wrap-label2]
:handler handler}
:post {:my-data2 :post
:middleware [wrap-label2]
:handler handler}}]
{:data {:my-data0 :global
:middleware [wrap-label0]}}))]
(api {:request-method :get
:uri "/ping"})
(api {:request-method :post
:uri "/ping"})
)
It is executed at compile time so you also need to reason about it a bit differently 😅
output above is {:status 200 :middleware [:post :intermediate :global]}
All route data is merged before it is fed to the middleware compiler. So reusing middleware at multiple levels and taking this data as input doesn’t really make sense
Maybe you can give a small example?
I want to perform some side effect per route endpoint per method,like increment a counter Not at the computer at the moment so hand waving
Ah i see. I think it’s possible. I just wonder now if you need the compiled middleware. I think the benefit of compiled middleware is that you can skip things, but that’s not what you want then
I want to compile the middleware because the counters exist in a shared registry and I want to wrap with them instead of look them up
Yeah I’m sure everything is possible. Just need to try some things
If you can give an example I can help you further
You can manually feed all the data you need per endpoint (e.g. the fn that needs to update the registry). Maybe what is missing is a way to know where you are just from the route data. That would allow you to it automatically I guess
That's exactly what I want to do. I already have the route data I care about (verb, endpoint name), why feed it manually?
Then I think you are set. I’m just missing what you want to do globally then
As in global middleware. Your registry is global, but it’s not like in my examples where you reuse the same middleware on multiple levels. I think