Route paramter constraints #2007
Replies: 1 comment 1 reply
-
|
I definitely like the annotation or the As for your consideration points, I don't think you'd ever want to have 2 separate action classes that use the same route path and different constraints... unless maybe they're different HTTP methods? I feel like that would be strange, but they would still match different actions anyway, so I say we probably don't want the same path with different constraints to match different actions. So options 2 is probably the best way. Related to typed params, when I use here Line 196 in 5922ff8 and here Line 206 in 5922ff8 where these are statically set to Thanks for putting this all together and getting the discussion started! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
We've touched on this in the Discord: adding constraints for dynamic parameters in routes. Possible API approaches could be either with an annotation:
With another argument:
Or like
route_prefixwith a dedicated macro:Aside from a regex, we could also make it accept a type:
And test with
UUID.parse?. The supported types can be limited to the most commonly used and expand later.Or even use a proc:
Considerations
I've been looking at the code to find the best way to implement this. My primary concern here is the speed of the router. Ideally I would rather not touch
LuckyRouterat all. And this brings me to the first consideration:Do we want to allow the same path, but with different constraints, and route each variant to a different action?
→ So
/some/:routewith/\A\d+\z/would route to action A, and/some/:routewith constraint/\A[a-z]+\zto action B.LuckyRouterto test a matched path to the regex and continue lookup if it doesn't match.Lucky::RouteHandlerand continue to the following handlers, which are static files in the default setup. This is also the easiest and least intrusive approach.My feeling is, start with option 2 because it gives us safer and more controllable routing without a possible performance hit, and implement option 1 if there's a need for it (YAGNI).
Typed params
Another thing we briefly discussed is casting matched params to their respective types. I think this will be difficult to achieve without braking things because
params.get(:uuid)will then suddenly return all kinds of unions. I think a better approach would be adding a method overload forLucky::Params#get:If there's a constraint on the path param, you can be 100% sure that the cast to
UUIDwon't fail. But even then we could add the safe variant:This would then test the existence of the value and test if it matches the required format, and return
Nilid it doesn't match.Thoughts?
Beta Was this translation helpful? Give feedback.
All reactions