-
Notifications
You must be signed in to change notification settings - Fork 140
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
Unfathomable behaviour of params when mixin parametric and static routes #161
Comments
I have setup a git repository with the files used for investigating those problems here: |
Thanks for the research.. it would take some time to digest. There are definitely some bugs especially with the ignoreTrailingSlash option. Would you like to send a PR to fix the first problem you have identified? Thanks. |
I added a little summary a the top since the Issue is quite long. @mcollina thanks in advance for your time on this issue 🙏 The first problem aka empty parameter when its first matched by a static route ? I think the problem is described/analysed here fastify/fastify#2261 (comment) The routing algorithm seems to be "greedy" and does not backtrack to the last possible parametric route, when the static route matching does not end with a full match. In the comments, someone said that backtracking is not really an option because of performance. ==================================== Also, not described here, but on our production server we have a strange behaviour were the route parameters are partially eaten by the static routes, and the parametric route receives only part of the value Our route tree looks like this
and if we the I was not able to reproduce in a simpler setup. |
The first bug I can see is:
This is wrong, as it should have the same behavior with or without Note that this problem is independent of the greedy algorithm (that we are unlikely to change). I think it would be best to separate actual bugs (like the above) from the decisions. A strategy that I have used in the past to deal with those cases is to create routes for the static paths with a param. In your first example, I would add:
Adding those automatically can be feasible. |
This issue was fixed. I added a test here #263. We can close this. |
Hello,
Version: 3.0.4
This issue is similar too #149
but with even more strange behaviour
I found those problems while working with a Fastify server.
long story short
If your parametric routes overlap with static routes
The exact behaviour is greatly affected by
ignoreTrailingSlash
option.setup
Given a basic setup file like
I have a lot of different troubles when mixing parameter and static routes
only one parameter, with or without ignoreTrailingSlash option
with routes definitions like
Route print output:
Requests
GET /static/param1
-> 200
param1
GET /static/param2
-> 200
param2
GET /static/paramOther/next
-> 200
{ route="next", paramA="paramOther" }
GET /static/param1/next
withoutignoreTrailingSlash
-> 200
{ route="next", paramA="param1" }
GET /static/param1/next
withignoreTrailingSlash
-> 200
{ route="next", paramA="" }
-> first problem hereSo I read fastify/fastify#2261 (comment) and I can understand the "greedy match algorithm" logic and conclusion, but behaviour can get even more strange, as I show in following examples.
one route with two parameters vs fully-static routes
with ADDED routes definitions like
Route print output
Requests
GET /static/param1/next/param3
-> 200
param1-3
GET /static/param1/next/param4
-> 200
param1-4
GET /static/paramOther/next/paramOther2/other
-> 200
{ route="other", paramA="paramOther", paramB="paramOther2"}
GET /static/param1/next/paramOther/other
withoutignoreTrailingSlash
-> 200
{ route="other", paramA="", paramB="paramOther" }
-> same problem here, paramA disappears, but ! without ignoreTrailingSlash
GET /static/param1/next/paramOther/other
withignoreTrailingSlash
-> 404
-> yet another behaviour
GET /static/param1/next/param3/other
with or withoutignoreTrailingSlash
-> 404
-> in both cases
one route with two parameters and multiple path fragments with the same text, vs fully-static routes
with ADDED routes definitions like
Routes print output
Requests
GET /static/paramOther/next/paramOther/next
-> 200
{ route="other", paramA="paramOther", paramB="paramOther2"}
GET /static/param1/next/paramOther/next
withoutignoreTrailingSlash
-> 200
{ route="other", paramA="", paramB="paramOther" }
-> same problem as before
GET /static/param1/next/paramOther/next
withignoreTrailingSlash
-> 404
-> same problem as before
GET /static/param1/next/param3/next
withoutignoreTrailingSlash
-> 200
{ route="other", paramA="paramOther" }
-> new problem, paramB value is in paramA !
GET /static/param1/next/param3/next
withignoreTrailingSlash
-> 200
{ route="other", paramA="" }
-> new problem
So, apparently, if I define route with repeating fragments (
/next
here), it can mess up the parameters value affectation.with 3 levels of parameters
with ADDED routes definitions like
Routes print output
Requests
GET /static/paramOther/next/paramOther2/other/paramOther3/last
withoutignoreTrailingSlash
-> 200
{ route="last", paramA="paramOther", paramB="paramOther2", paramC="paramOther3" }
GET /static/paramOther/next/paramOther2/other/paramOther3/last
withignoreTrailingSlash
-> 200
{ route="last", paramA="", paramB="paramOther2", paramC="paramOther3" }
-> paramA is lost
GET /static/param1/next/paramOther2/other/paramOther3/last
with|withoutignoreTrailingSlash
-> 404
-> new behaviour
GET /static/param1/next/param2/other/paramOther3/last
with|withoutignoreTrailingSlash
-> 404
GET /static/param1/next/param2/other/param3/last
with|withoutignoreTrailingSlash
-> 404
So here the behaviour is yet again slightly different,
ignoreTrailingSlash
eats the first param if it's different from the static routes, but as soon as the first parameterparamA
matches one of the defined static routes (hereparam1
), I get only 404.fully-dynamic routes vs mixed dynamic/static routes
if I defined routes starting with dynamic parameters dans ending with a static part like
Then
ignoreTrailingSlash
I have no problemsignoreTrailingSlash
I have the "matching parameters are empty" problems as usualconclusion
I have read:
I am aware of the matching priority of static vs parameters routes:
But as shown here, when static routes overlap with parametric routes, the resulting matching behaviour and parameters values for the parametric routes are too much random, depending on
ignoreTrailingSlash
option.You can even get some parameters values extracted in another parameter key.
The fact that repeating route fragments change the behaviour is also hard to predict.
I feel the only maintainable approach for a dev team would be to completely seggregate static and parametrics routes, for example with starting prefixes like
/static
and/dynamic
at url root.Otherwise the risk of breaking the routers when adding a route of changing a part of a route are too big.
The text was updated successfully, but these errors were encountered: