This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-09-21
Channels
- # admin-announcements (1)
- # announcements (6)
- # babashka (8)
- # beginners (134)
- # calva (18)
- # chlorine-clover (1)
- # cider (6)
- # circleci (6)
- # clj-commons (111)
- # cljsrn (13)
- # clojure (95)
- # clojure-australia (2)
- # clojure-europe (15)
- # clojure-nl (1)
- # clojure-spec (52)
- # clojure-uk (17)
- # clojurescript (4)
- # datavis (9)
- # datomic (8)
- # docker (2)
- # emacs (15)
- # events (7)
- # fulcro (6)
- # graphql (1)
- # gratitude (1)
- # introduce-yourself (2)
- # kaocha (8)
- # meander (87)
- # minecraft (2)
- # music (2)
- # off-topic (20)
- # portal (119)
- # releases (1)
- # reveal (55)
- # shadow-cljs (34)
- # sql (36)
- # tools-deps (9)
- # vim (8)
- # xtdb (39)
hello, trying to figure how to parte pedestal-like nested URL format using meander, for example, go from
["v1"
["/foo"
["/baz" {:post baz-handler}]]
["/bar"
{:get bar-handler
:post post-bar}]]
to
[{:url "v1/foo/baz" :method :post :handler baz-handler}
{:url "v1/bar" :method :get :handler bar-handler}
{:url "v1/bar" :method :post :handler post-bar}]
I guess I gotta use cata
, but not sure how
(m/rewrite '["v1"
["/foo"
["/baz" {:post baz-handler}]]
["/bar" {:get bar-handler :post post-bar}]]
(m/with [%1 (m/map-of !methods !handlers)
%2 [!paths . (m/or %2 %1) ...]]
%2)
[{:url !paths :method !methods :handler !handlers} ...])
cool, that almost solves, the missing part is accumulating the previous routes
haha, would love to hear, I’m trying to figure on my end as well, if I figure I’ll post here
Give this a try
The first rewrite does the data re-organization that you're looking for but suffers from nested vectors (this is often a result of using cata
).
The second rewrite "flattens" the structure
cool, I guess the last rewrite can be replaced with flatten
, got the same result here
not sure if its a fixable issue, but when I tried with a real longer structure, it did stack overflow 😅
It's funny - I'm so used to using meander that I reached for meander to flatten the data without even thinking of flatten
🙂
cata
does stack-based recursion so a sufficiently deep structure could result in an overflow, I guess
Let me see if I can rewrite it to avoid some of the recursion
I don’t think its that deep, from a quick look I guess its less than 10 depth
Can you post the structure?
I assume you're getting the SO from the first rewrite?
sadly no, but there are a few other patterns that needs to be taken in account
and I guess those are screwing it up
Unfortunately, I'm not very familiar with these routing data structures
I can make a shorter version that has more of those features, let me check
(m/rewrite [:start 1]
[:start (m/app inc ?x)]
(m/cata [:end ?x])
[:end ?x]
~(str "end with ?x = " ?x))
found a simple stack overflow example:
'["v1"
["/foo"
["/baz" {:post baz-handler}]
["/other" []]]
["/bar"
{:get bar-handler
:post post-bar}]]
sometimes instead of a map, its a vector with interceptors on the right side
ah, yeah. I can see how this would overflow
I'll take a crack at this data structure
feels a little ambiguous case, curious to see what you come with for that 😉
you read my mind
unctions? fI'm guessing the vector of interceptors is always a vector of
functions?
What does the result for this look like?
the real one looks more like this:
'["v1"
["/foo"
["/baz" {:post baz-handler}]
["/other" [[:interceptor
[{:features {:policy-authz-enabled? false},
:interceptor [:scope
{:scope "xxx"}]}
{:features {:policy-authz-enabled? true},
:interceptor [:scope
[{:policy "yyy"}]]}]]]]]
["/bar"
{:get bar-handler
:post post-bar}]]
but I’m not sure all possible variations (like if they always start with double vector)
I've got a meeting in 5 minutes but I'll pick this up after
thanks, I’ll keep playing here too
seems like a notable difference is that those never start with strings at the beginning of the vector
only routes do that
(m/rewrite '["v1"
["/foo"
["/baz" {:post baz-handler}]]
["/bar" {:get bar-handler :post post-bar}]]
(m/with [%1 (m/map-of !methods !handlers)
%2 [(m/app #(str (last !paths) %) !paths) . (m/or %2 %1) ...]]
%2)
[{:url !paths :method !methods :handler !handlers} ...])
I can't make it any shorter @U066U8JQJ
looks nice!
on the large example it didn’t match though =/
but I’ll play with it
it probably because of the interceptors in the middle
omitting other is good
the longer one currently returns nil
, so something is going bad in the middle, I’m trying to get a case to reproduce with your solution
(m/rewrite '["v1"
["/foo"
["/baz" {:post baz-handler}]
["/other" [[:interceptor
[{:features {:policy-authz-enabled? false} ,
:interceptor [:scope
{:scope "xxx"}]}
{:features {:policy-authz-enabled? true} ,
:interceptor [:scope
[{:policy "yyy"}]]}]]]]]
["/bar"
{:get bar-handler
:post post-bar}]]
(m/with [%1 (m/map-of !methods !handlers)
%2 [(m/pred string?) _]
%3 [(m/app #(str (last !paths) %) !paths) . (m/or %3 %2 %1) ...]]
%3)
[{:url !paths :method !methods :handler !handlers} ...])
\other
catches under %2
, which is defined in the simplest possible way, [string? whatever]
here is an example that’s going off, but not the main problem yet:
(m/rewrite '["v1"
["/foo"
[:some-interceptors]
["/baz" {:post baz-handler}]
["/other" [[:interceptor
[{:features {:policy-authz-enabled? false},
:interceptor [:scope
{:scope "xxx"}]}
{:features {:policy-authz-enabled? true},
:interceptor [:scope
[{:policy "yyy"}]]}]]]]]
["/bar" {:get bar-handler :post post-bar}]]
(m/with [%1 (m/map-of !methods !handlers)
%2 [(m/pred string?) _]
%3 [(m/app #(str (last !paths) %) !paths) . (m/or %3 %2 %1) ...]]
%3)
[{:url !paths :method !methods :handler !handlers} ...])
(in this case the :some-interceptors
should be ignored)
anyway you guys are meander masters, its already really helpful 🙇
not so much
I see that it is probably wrong, because it does not return a map with the path :url foo/bar
😕
It would be nice if @U06MDAPTP offered a solution
I have no idea how to better concatenate urls into one, and what I've done doesn't always work
the examples you posted are nice as well, I’ll spend some time to understand and learn those patterns 🙂
Thanks for showing with
@U0BBFDED7 ! I was aware of it but I don't think I've ever used it before
this worked!
(m/rewrite
(-> data :ig/system :pipo.module/web-routes :routes ffirst)
(m/with [%route-map (m/map-of !methods !handlers)
%item [(m/pred string?) _]
%interceptors [(m/pred keyword?) . _ ...]
%all [(m/app #(str (last !paths) %) !paths) . (m/or %all %item %interceptors %route-map) ...]]
%all)
[{:url !paths :method !methods :handler !handlers} ...])
thank you again folks!
I celebrated too soon, @U0BBFDED7 I found this way to concatenate is not doing the stack as expected, on the base example it outputs:
[{:url "v1", :method :post, :handler baz-handler}
{:url "v1/foo", :method :get, :handler bar-handler}
{:url "v1/foo/baz", :method :post, :handler post-bar}]
but it should be
({:url "v1/foo/baz", :method :post, :handler baz-handler}
{:url "v1/bar", :method :get, :handler bar-handler}
{:url "v1/bar", :method :post, :handler post-bar})
(which is the result given frmo the @U2845S9KL solution)now trying to work more on the mark example to add the interceptors part
I thought you guys already had a solution so I didn't pick up the interceptor piece. I'll give it a look tomorrow morning
thanks, this is the example I’m working on top of now:
'["v1"
["/foo"
[:some-interceptors]
["/baz" {:post baz-handler}]]
["/bar" {:get bar-handler :post post-bar}]]
you can forget the value as vectors, that wasn’t a thing, just the interceptors in the middle 🙂
got it 😄 🎉
(-> '["v1"
["/foo"
[:bla :me []]
["/baz" {:post baz-handler}]]
["/bar" {:get bar-handler :post post-bar}]]
(m/rewrite
[?path (m/map-of !action !handler)]
[{:url ?path :method !action :handler !handler} ...]
[?path-prefix [(m/pred keyword?) & _] & ?rest]
(m/cata [?path-prefix & ?rest])
[?path-prefix [?path-suffix & ?deeper-or-handlers]]
(m/cata [(m/app str ?path-prefix ?path-suffix) & ?deeper-or-handlers])
[?path-prefix . !deeper ...]
[(m/cata [?path-prefix !deeper]) ...])
flatten)
that was fun to learn! thanks folks