-
Notifications
You must be signed in to change notification settings - Fork 1.9k
docs: Add description of conflicts between named and unnamed routes #9499
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
Conversation
It is worth adding tests if there is no case described. Add a note to changelog |
@neznaika0 yes, thank you for the advice! I was planning to add the test later, after receiving feedback, but I’ll do it now. And am I correct in understanding that the changelog should just be left here as a message, rather than editing the If so, here it is: |
I also fixed DefinedRouteCollector. Previously, it would remove a route's name when it matched the route's URI. |
No.Edit file https://github.com/codeigniter4/CodeIgniter4/blob/develop/user_guide_src/source/changelogs/v4.6.1.rst |
I wasn't aware that a route's name is always filled. While this change may fix the bug, it may also introduce a BC break for users who took advantage of this fact in their apps. @yllumi, I know you have a project that involves a more advanced use of Routes. Would this change affect you? Do you use route names even if they're not defined? It would be nice to get an opinion on this from users who use Routes in more advanced ways. Anyway, I think this should rather go into the 4.7 branch. |
No @michalsn, in the projects and packages I've developed related to routing, I neither use nor modify the named route mechanism. So it seems the change above will not affect my packages. |
@yllumi Ok, thank you. |
I always name each route. For example, according to the action: user.list user.edit user.delete. I didn't get any collisions |
I'm worried about cases where developers might not realize they're relying on named routes without explicitly defining them. For example: // Route is defined without a name:
$routes->get('edit', 'PostController::edit');
// But this still works:
d(url_to('edit'), route_to('edit')); If we change this behavior and stop auto-filling route names, it could break code like this - especially if people have been unknowingly depending on it. I'm not sure how common this pattern is, but it could potentially cause problems. |
Hmm, yes, this does seem dangerous. However, keeping the current mechanics introduces a bug that causes inconsistent behavior with flawed logic, as I described in the issue. It's a tough question🤔 |
There is a practice in the framework to use temporary Config/Feature.php flags. This does not mean that everything can be added there. But it allows us to experiment. In the best case, you can replace the routes service with your own. |
After thinking about it, I can't decide if this should be changed. The named routes have been working this way since the beginning. Looking at the code, it was supposed to work this way. We should work on the user guide to describe it correctly. Now, it sounds like only using the The impact of the potential change seems too big. Not sure what others will think about the feature flag for this, but I'm not a fan. |
This still needs to go to 4.7 branch, as changed behavior |
This is true, but even then - the impact of this change could be quite large - I'm not sure we should go for it. That's why I'm trying to gather more opinions. |
Please correct me if I'm wrong. This PR introduces two changes:
For item 1, I can approve as it will force users to provide a route name. However, since it is a change in behavior it should go to 4.7. |
I'm particularly worried about the scenario described here: #9499 (comment). Catching things like this in the existing apps may be a headache. This makes updating particularly difficult. |
@michalsn Actually, this fix will not affect the existing behavior: // Route is defined without a name:
$routes->get('edit', 'PostController::edit');
// But this still works:
d(url_to('edit'), route_to('edit')); This fix will only impact the following behavior: // Route is defined without a name:
$routes->get('edit', 'PostController::edit');
// Route is defined with the name like the path above:
$routes->get('user/edit', 'UserController::edit', ['as' => 'edit']);
// But this still works:
d(url_to('edit'), route_to('edit')); And yes, it seems like the fix of |
That's true - sorry everyone. I didn't notice that normal routes are also checked in the Please change the branch to You should list changes under the sections: breaking changes (since |
@michalsn Oh, I discovered that my fix is order-dependent. If you declare a named route first, and then declare a route without a name but with a path that matches the name of the previous route, the latter won't work: $routes->match(['GET', 'POST'], 'edit/(:num)', 'PostController::edit/$1', ['as' => 'edit']);
$routes->match(['GET', 'POST'], 'edit', 'PostController::edit');
// request of /edit returns 404 Sorry about that! Actually, I can't think of a solution to this problem that wouldn't break the current incorrect behavior, where routes without a clearly defined name work as if they have a name. Perhaps, in this case, it would be best to keep the current behavior but document it as transparently as possible. |
@Elias-Black Fair enough. Would you like to prepare the clarification for that in the user guide? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds good to me. Thank you.
Thanks @michalsn and everyone else for the time spent! This was important to me because I spent some time experimenting and going through the documentation due to this bug or undocumented functionality. I wouldn't want anyone else to run into the same issue. |
@Elias-Black We also appreciate the improvements to the user guide, as they may help many developers in the future. Thank you one more time. |
It fixes the case described me in the forum topic https://forum.codeigniter.com/showthread.php?tid=92672
If we have two routes and the name of the second route is the same as the path of the first route, they conflict, and the second route is not added to the list of all routes.
So, with this route configuration, we get a 404 on /edit/10.