-
Notifications
You must be signed in to change notification settings - Fork 262
Description
I have an existing routing structure I'm trying to migrate from Bidi. It uses regular expressions quite heavily. Bidi supports these quite happily: https://github.com/juxt/bidi#regular-expressions. However, I'm not sure how to translate these into Reitit routes.
Here's one of our simpler examples:
(let [rtr (r/router ["/"
["" ::home]
["inbox" ::inbox]
["teams" ::teams]
["teams/:team-id-b58/members" {:name ::->members
:parameters {:path {:team-id-b58 (partial re-matches #"[a-z]")}}}]])]
[(r/match-by-path rtr "/")
(r/match-by-path rtr "/inbox")
(r/match-by-path rtr "/teams/123/members")
(r/match-by-path rtr "/teams/abcdefg/members")])output
[#reitit.core.Match{:template "/", :data {:name :user/home}, :result nil, :path-params {}, :path "/"}
#reitit.core.Match{:template "/inbox", :data {:name :user/inbox}, :result nil, :path-params {}, :path "/inbox"}
#reitit.core.Match{:template "/teams/:team-id-b58/members",
:data {:name :user/->members,
:parameters {:path [{:team-id-b58 #object[clojure.core$partial$fn__5927
0x4bedf1bc
"clojure.core$partial$fn__5927@4bedf1bc"]}]}},
:result nil,
:path-params {:team-id-b58 "123"},
:path "/teams/123/members"}
#reitit.core.Match{:template "/teams/:team-id-b58/members",
:data {:name :user/->members,
:parameters {:path [{:team-id-b58 #object[clojure.core$partial$fn__5927
0x4bedf1bc
"clojure.core$partial$fn__5927@4bedf1bc"]}]}},
:result nil,
:path-params {:team-id-b58 "abcdefg"},
:path "/teams/abcdefg/members"}]
Here there are no conflicts, but Reitit is matching both of the routes. If I try to load /teams/123/members in our frontend app, it crashes with an exception once request coercion runs:
:app.boot/init-router event error: Request coercion failed
:type :reitit.coercion/request-coercion]
[:coercion ]
[:value {:team-id-b58 "123"}]
[:in [:request :path-params]]Ideally I'd like those /teams/123/members to not be matched at all so I can serve a default "not found" route.
Then we have a more challenging example:
(let [rtr (r/router ["/"
["" ::home]
[":item-id" {:name ::item
:parameters {:path {:item-id (partial re-matches #"[a-z]{16,20}")}}}]
["inbox" ::inbox {:conflicting true}]
["teams" ::teams {:conflicting true}]
["teams/:team-id-b58/members" {:name ::->members
:parameters {:path {:team-id-b58 (partial re-matches #"[a-z]")}}}]
])]
[(r/match-by-path rtr "/")
(r/match-by-path rtr "/inbox")
(r/match-by-path rtr "/itemwithlongname")
(r/match-by-path rtr "/teams/123/members")
(r/match-by-path rtr "/teams/abcdefg/members")])output
[#reitit.core.Match{:template "/", :data {:name :user/home}, :result nil, :path-params {}, :path "/"}
#reitit.core.Match{:template "/:item-id",
:data {:name :user/item,
:parameters {:path [{:item-id #object[clojure.core$partial$fn__5927
0x4f1cba3b
"clojure.core$partial$fn__5927@4f1cba3b"]}]}},
:result nil,
:path-params {:item-id "inbox"},
:path "/inbox"}
#reitit.core.Match{:template "/:item-id",
:data {:name :user/item,
:parameters {:path [{:item-id #object[clojure.core$partial$fn__5927
0x4f1cba3b
"clojure.core$partial$fn__5927@4f1cba3b"]}]}},
:result nil,
:path-params {:item-id "itemwithlongname"},
:path "/itemwithlongname"}
#reitit.core.Match{:template "/teams/:team-id-b58/members",
:data {:name :user/->members,
:parameters {:path [{:team-id-b58 #object[clojure.core$partial$fn__5927
0x5a45ffe6
"clojure.core$partial$fn__5927@5a45ffe6"]}]}},
:result nil,
:path-params {:team-id-b58 "123"},
:path "/teams/123/members"}
#reitit.core.Match{:template "/teams/:team-id-b58/members",
:data {:name :user/->members,
:parameters {:path [{:team-id-b58 #object[clojure.core$partial$fn__5927
0x5a45ffe6
"clojure.core$partial$fn__5927@5a45ffe6"]}]}},
:result nil,
:path-params {:team-id-b58 "abcdefg"},
:path "/teams/abcdefg/members"}]
We have a root "item-id" route which is matched by a regular expression. This lives at the root of the app, so we can't prefix it with /item/:item-id and put it under another route prefix. Is there a way to achieve this route with Reitit? I understand it might be a bit slower because it would need to evaluate a regex or similar on the fly, but it is the routing structure we need to live with.
Similar to, but different from #721.