reitit

danielcompton 2025-02-24T02:54:03.273489Z

Hi folks, I’m trying to migrate from Bidi to Reitit and have a few routes that are proving to be a bit tricky. We used regex based routes in bidi quite heavily and I’m not sure how to apply them in Reitit. I wasn’t sure whether to discuss them here or in the bug tracker, so I opened some bugs there: https://github.com/metosin/reitit/issues/721, https://github.com/metosin/reitit/issues/722

danielcompton 2025-02-24T09:04:13.850019Z

@ikitommi so is there no way to express a Regex based route in Reitit like shown in https://github.com/metosin/reitit/issues/722? In theory, could there be a Regex based router which could dispatch on these kinds of routes?

ikitommi 2025-02-24T15:08:50.297149Z

answered on the issue. I think there might be a simple way, but nothing built-in, sorry

danielcompton 2025-02-25T20:20:47.237219Z

Nice, thanks! I’ve opened a PR to start a discussion about possibly building this in more directly too: https://github.com/metosin/reitit/pull/723

2025-02-24T03:11:32.274899Z

in the docs https://github.com/metosin/reitit/blob/master/doc/basics/route_conflicts.md the key is :conflicting (no ? at the end) so maybe that's the issue?

danielcompton 2025-02-24T03:14:39.765219Z

Thanks for catching that. I’ve retested and updated the issues, but it doesn’t resolve the routing issues

valerauko 2025-02-24T03:17:31.375829Z

You can try composing routers so that the non-conflicting routes will have as good performance as it gets while conflicting ones can still be used https://cljdoc.org/d/metosin/reitit/0.7.2/doc/advanced/composing-routers#performance

valerauko 2025-02-24T03:20:50.873839Z

You can also try setting :conflicts nil on the whole router to see if there's some other issues too

danielcompton 2025-02-24T03:23:30.183469Z

Could I use that to satisfy something like these routes?

/inbox
/teams/:uuid
/:uuid
;; also have a not found route when it doesn't match
My existing routing structure has item IDs (UUIDs) at the same nesting level as /inbox and /teams. How could I setup routing so that I could match on all of these routes?

valerauko 2025-02-24T03:26:53.539479Z

First goal I guess is just to get it work and this should

(r/router
 [["/"
   ["inbox" ::inbox]
   ["teams/:uuid" ::team]
   [":uuid" ::uuid]]]
 {:conflicts nil})

danielcompton 2025-02-24T03:30:52.450049Z

(let [rtr (r/router ["/users"
                     ["" :user/list]
                     ["/new" :user/new]
                     ["/:id" :user/detail]]
                    {:conflicts nil})]
  (map #(get-in % [:data :name]) 
       [(r/match-by-path rtr "/users")
        (r/match-by-path rtr "/users/new")
        (r/match-by-path rtr "/users/123")]))
=> (:user/list :user/new :user/detail)
Nice! Thanks

valerauko 2025-02-24T03:32:10.365039Z

As for your issue with regex param matching, I don't know of a way to do that (but it could be possible nonetheless). I'd use a middleware to handle coercion errors and return 400 or 404 or whatever appropriate

danielcompton 2025-02-24T03:33:27.544749Z

Is it “ok” to have to use {:conflicts nil} on your routes? I understand it will have a performance impact, but is there anything else it would affect?

valerauko 2025-02-24T03:37:29.453169Z

Not that I know of... It'll use a less-efficient (probably linear) routing algo but it'll work just fine. I've used it without issues while implementing a mastodon-compatible api

👍 1
valerauko 2025-02-24T03:41:54.670029Z

You can try looking at how it quarantines conflicting routes and play around with nested routers to optimize that, but I've never done that myself https://github.com/metosin/reitit/blob/30fd739fa987ba3538b4ad66028241f74778d63c/modules/reitit-core/src/reitit/core.cljc#L354

ikitommi 2025-02-24T06:13:17.534989Z

> Is it “ok” to have to use {:conflicts nil} on your routes? I understand it will have a performance impact, but is there anything else it would affect? @danielcompton yes it is, and for simplicity, this could be the default (and could be for 1.0.0, when it’s ok to break things). What happens here: 1. only the conflicting routes will be put behind linear-router (which is the default router algo in compojure, bidi etc) 2. rest will be served with best router algo: tree, static, whatnot … as all router algos satisfy the same Router protocol, they behave exactly the same.

ikitommi 2025-02-24T06:14:28.159399Z

performance is not optimal, but just for the conflicting routes and it will still be order of magnitude faster than most of the regex-based routers.

ikitommi 2025-02-24T06:15:17.684129Z

but, there are no guards (e.g. router based path parameter type) in reitit routing, like there is in bidi.