New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Only first route registration works #48
Comments
It looks like in TrieRouter.swift:84 no attempt is make to ensure that the parameter in the current request is of the type listed in the registered route. Instead if the // no constants matched, check for dynamic members
if let parameter = currentNode.parameter {
// if no constant routes were found that match the path, but
// a dynamic parameter child was found, we can use it
let value = ParameterValue(
slug: String(data: parameter.value, encoding: .utf8) ?? "",
value: path.routerParameterValue
)
parameters.values.append(value)
currentNode = parameter
continue search
} Because of this, Then everything falls apart when the user tries to do let param = try req.parameters.next(String.self) within their responder because the |
This issue has been reported before: vapor/http#206 The TLDR is that for the TrieRouter to handle types like this, you get a performance hit that would cause a lot of apps to be slower for a feature they don't even use. But if there is a good way for the router to solve the ambiguity, then a PR or issue outlining how to do that is welcome. |
@calebkleveter but here we have different number of parameters, I don't think that counting number of parameters will do a performance hit. Anyway it looking like a bug, because routing is performed using |
It's true that that would probably be easier to implement that in a performant fashion, but I'm not sure that would be the correct solution because that only fixes half the problem (from my perspective). The reason I say that is because if someone creates routes like you did, with different static route components, everything would work fine:
But if the routes are only dynamic (I get rid of the static parameter), it breaks as you explained when you opened this issue:
This would be unexpected behavior from the user's point of view, and so, a bug. |
Isn't it better to fix 1/2 a bug than no bugs? |
+1 to what @calebkleveter said. This is definitely an implementation detail of the TrieRouter, but I think this limitation does make some sense even at a higher level. At least in RESTful route design, having
Here So, if anything, I would think we should make registering conflicting route hierarchies a more obvious error. |
I don't think the additional complexity or performance cost required to allow for multiple dynamic children per node would be worth it. This problem seems better solved by the higher level APIs for registering route handlers in Vapor. See https://forums.swift.org/t/named-routing-parameters/19434 for more discussion about a proposed improvement to these APIs. |
Steps to reproduce
I've created fresh test repository: https://github.com/Sorix/RouterIssue
We have 2 paths:
Let's try to call second route:
curl "http://localhost:8080/test/12/secondComponent/"
Expected behavior
Vapor will correctly route and call
testController.int
.Actual behavior
Vapor always calls firstly registered route (
controller.string
). That's why we get the error:If we switch registrations, another route will work, but both will never work.
I don't think that my issue is relevant to #45 because I use different count of pathComponents.
Environment
The text was updated successfully, but these errors were encountered: