-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Routing][WIP] Add priorities to routing component #26132
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
Status: Needs work |
Could be useful :) Maybe also display the priorities on the |
Something like his has been proposed before in #11753
This is not true. It creates the route in the order the methods are defined. See http://php.net/manual/de/reflectionclass.getmethods.php#115197 |
@Tobion you are right: reordering methods in a single PHP class is simple. However, the problem I sometimes have faced is that I need the routes of some controller to be defined before some other controller. However, with this default config: controllers:
resource: ../../src/Controller/
type: annotation Symfony loads controllers alphabetically, so you can't control this in any way ... except importing controllers manually from |
If we could prevent this from being happening at all, that'd be best IMHO, as this will add complexity. |
I agree with @nicolas-grekas |
* @param string $name The route name | ||
* @param Route $route A Route instance | ||
*/ | ||
public function addWithPriority($name, Route $route, int $priority = 0) |
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.
Instead of this, I would have used the deprecation mechanism with args and merged this with addRoute
(only one entrypoint to add a route would then be used)
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.
I agree
@nicolas-grekas: I mean, sure we could treat this as a documentation issue (and I would be willing to work on a doc PR for that if that's the decision), but if the problem is "ordering routes is impractical when using annotations", that's pretty much a "won't fix". That's fine of course if I'm fairly alone in having it, but I'm not sure that's the case. I might do some kind of informal poll to see if people think this is a real issue that should be solved, or if they don't mind switching to a different route format for routes where order matters. |
Possible solutions:
Moreover, a 3nd solution could be to specify only the highest priority controller in the config before loading the rest:
Unfortunately, this solution is not working because the routes defined in the |
Instead of adding priorities here, can we do it at the annotations loader one? Could be a new parameter on annotations to control the order in one |
@nicolas-grekas: It would help, but I don't think that would solve the issue completely. It would be good to be able to order annotation routes in relation to routes defined in yaml or xml, not just among other annotation routes. |
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.
Let's unlock this one :)
Still interested in finishing it?
Annotations and loaders should be updated also.
*/ | ||
private $routes = array(); | ||
private $prioritizedRoutes = array(); |
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.
routesByPriority?
@@ -48,12 +55,13 @@ public function __clone() | |||
* It implements \IteratorAggregate. | |||
* | |||
* @see all() | |||
* @todo Change return type to Iterator|Route[] in 5.0 |
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.
should be removed
/** | ||
* @var int[] | ||
*/ | ||
private $priorities = array(); |
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.
routePriorities?
* @param string $name The route name | ||
* @param Route $route A Route instance | ||
*/ | ||
public function addWithPriority($name, Route $route, int $priority = 0) |
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.
should be removed and a third arg added to add()
, using the common technique we use elsewhere (docblock @param
+ commented argument in /* ...*/
+ func_num/get_arg(s)
foreach ($collection->all() as $name => $route) { | ||
unset($this->routes[$name]); | ||
$this->routes[$name] = $route; | ||
foreach ($collection->prioritizedRoutes as $priority => $routes) { |
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 breaks classes extending RouteCollection
- we might need a new method to get routes by priorities
@nicolas-grekas Sure, I'll take a fresh look at it this weekend. |
@magnusnordlander friendly ping ;) |
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.
If the use case is to manage priorities for annotations (I don't think that managing priorities for other loaders is useful), then, what about managing priorities directly in the annotation directory loader?
* @param string $name The route name | ||
* @param Route $route A Route instance | ||
*/ | ||
public function addWithPriority($name, Route $route, int $priority = 0) |
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.
I agree
Closing in favor of #35608 |
…olas-grekas) This PR was merged into the 5.1-dev branch. Discussion ---------- [Routing] add priority option to annotated routes | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | Deprecations? | yes | Tickets | Fix #26132 | License | MIT | Doc PR | - This PR allows defining the priority of routes using annotations: `@Route(name="foo", priority=10)` As requested [in this comment](#26132 (review)), priority is reserved to using annotations. For other formats, the order works fine. Commits ------- 8522a83 [Routing] add priority option to annotated routes
When using the Route annotation, route ordering is unpredictable, and if you need a route in one controller to be first/last (e.g. as a catch-all route), you can't reliably achieve this. Instead you have to resort to using one of the other configuration formats.
In order to remedy this, I'd like to propose the addition of priority to the routing system. I suppose that makes the route collection a priority ordered dictionary, instead of just an ordered dictionary. When adding a route to a route collection, you can optionally specify a priority (the default is 0). Routes with higher priority are sorted before routes with lower priority. Routes with the same priority are still sorted by when they were added to the collection.
Adding a collection to your route collection respects priority, and if the added collection contains a route with the same name, but a higher/lower priority, the order will be updated accordingly (same priority still means they are added last).
This PR is not done, I still need to add priority to loader(s), I do however want feedback on this early.