-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Routing]RouteSubscriberInterface #37786
New issue
Have a question about this 8000 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
Comments
That sounds like you‘re suggesting yet another way to load routes. Can you elaborate why the methods described in https://symfony.com/doc/current/routing/custom_route_loader.html don‘t work for you? |
To the best of my knowledge, annotations are the only approach for letting controllers define their own routes. Annotations are of course not code and don't always provide useful feedback when writing. Annotations appear to be very popular so the desire to define routes within the same file as the controller seems relevant. As opposed to using external routing files. My approach relies on the RoutingConfigurator which is basically a route builder and avoids the need for dealing with array keys and such. Basically it replaces annotations with code while staying inside of the same file. It is of course what the framework itself uses for PHP based routing configuration. Annotations are also a bit awkward to use outside of the framework. You need to load the doctrine annotation package which always seemed a bit strange to me. I'm just proposing a standard component level interface that could be used to move code from config/routes.php to individual controller classes with a minimum of effort. And could then potentially be used to automate the process of finding the route subscriber classes within the framework when building the route collection. I think this approach is also consistent with current efforts to move to more PHP based configuration. |
Actually, you can define routes in a That's probably the closest that you can get to php based configuration IMO 🤔 |
This requirement will be removed once #37474 is merged. |
Yep. And all I am doing is proposing a standard component level way for using PHP to define routes from inside of a class such as a controller class. A way that might enable a bit of automation at the framework configuration level. |
Actually, thanks to the
Automation is a good idea but IMO, the current "implementation" is not what Sf should target, the proposed implementation looks and feels like BTW, maybe s
8000
omething similar to the <?php
namespace App\Controller;
class HomeIndexAction implements RouteSubscriberInterface
{
public static function getRoutes(): array
{
return [
'index' => new Route('/')->setController($this, ['index']), // This code is not valid, just a example
];
}
public function index(Request $request): Response
{
// ...
}
} |
@derrabus as a bundle author, not having a feature like this is something that I missed more than once. As explained in the article that you linked, bundles can't really add dynamic routes to the application. The reason is this: https://symfony.com/doc/current/routing/custom_route_loader.html#using-the-custom-loader Even if your bundle defines a route loader, the user must always add some config manually to activate it. That's why you have to copy+paste some route config when using SonataAdmin, because it includes a loader that generates admin routes for your entities dynamically. Note that:
|
Also because you almost always want to mount the bundle routes under a prefix that you (the app) decide (the bundle should not do it). |
This proposal is geared more towards the application level as opposed to the bundle level. In my controller code I almost always add a prefix:
It's one reason I like using the configurator to define routes. All the hard work of dealing with prefixes is already done for you. I don't see any reason why we could not add an optional prefix argument to the interface:
That would of course become messy if the bundle had many controllers. But just like autowire is discouraged for bundles, I see no inherent reason why autoroute (to invent a term) could not also be discouraged for bundles. The current bundle routing approach works fine and could still be the recommended approach. |
Thought a bit more about bundles. I think this interface could be used in place of importing bundle routes.
I think this would make importing bundle routes completely independent of any bundle specific configuration functionality. The entry point would just be a class. Would not even have to be part of a Symfony bundle. |
One thing that I am perfectly confident of is that the decades old debate of using annotations vs code for configuration is not going to be solved in this thread. At the end of the day, whatever the community decides is fine by me. I do think the recent shift from using yaml to PHP for routes and services show that there is not a great deal of resistance to using PHP. I also find it somewhat interesting that Symfony never developed an annotation based system for configuring services. Plenty of other systems have one. I think it is important that anyone offering an opinion on this proposed interface be familiar with the RoutingConfigurator. This is not a question of directly instantiating route objects and dealing with all the arrays and array keys involved. The builder gives you quite a bit of code completion and error checking and whatnot. And yes there are plugins that can help with route annotations. I also feel that developers using the route component standalone might appreciate a more or less standard method of defining routes inside of controllers. As mentioned before, using annotations outside of the framework can a bit of a pain. Using code also opens up the possibility of adding helpers. One could, for example, imagine a CRUD route helper that would generate all the routes needed for a CRUD controller. And yes there are existing generators which emit seemingly endless streams of annotations. Still, it could be nice to have some code based helpers. I'll just end with the proverbial BlogController example. Anyone who has managed to read this far can make their own comparisons to annotations.
|
More than open to name changes. Subscribers sort of matches some other components. A single static method that provides additional configuration information. No conflict with route loaders or importers. I kind of think that having an unique name might actually avoid confusing it with a loader. Autoload is doing the hard work of finding and loading the file. I think if you squint a bit you could consider adding a route to the router as a type of subscribing. You are telling the router to provide this information when the url is matched. Sort of like the event dispatcher does when it receives an event. Of course there a few more steps between the router and the action but with a bit of hand waving, maybe people won't notice. Defining a helper trait as well is fine but one step at a time. |
I think that this is in fact a separate issue. If the feature that is being discussed here gets implemented, we should make sure, it does not create a way for bundles to automatically register routes.
And we should keep it that way. A bundle should not sneak in routes. We're talking about the public API exposed by the application. The application author should be in control here. I agree, that the activation of routes provided by a bundle could be standardized and simplified. But in the end, the application author should decide if and where the routes exposed by a bundle are mounted. |
@derrabus yes, I understand there might be some security/performance concerns. However, if I'm right, a bundle can override, delete and create any services in your application without manual intervention, it can override any Twig filter and function, etc. So, "shady bundles" can already destroy your application if they want. |
Taking over routes of the app is another level of shadiness. Especially because the public URL layout doesn't belong to bundle authors but to devs of the app. |
Based on some of the previous comments, I just want to emphasize that this proposal does not make any changes whatsoever to the existing route configuration processes. All it does i 8000 s provide a standard way for a class to act as a routes.php configuration file. Exactly the same functionality currently available using annotations. It's worth discussing how to use the interface to automate the discovery of routing file. Same as the annotation processor does. But the only thing that changes is replacing configurator import statements with static method calls. Warning: If this interface is accepted then expect a ServiceSubscriberInterface proposal as well. Same basic idea. Allow a class to configure itself as a service using a static method and the service configurator. |
I was definitely unclear. I was referring to the process of searching a directory (typically the Controller directory) and then using the AnnotationClassLoader to discover which classes have the route annotation and extracting the route information. I see no inherent reason why a PhpClassLoader could not accomplish that same task using the RouteSubscriberInterface. |
I'm 👎 on this proposal. PHP attributes will be a core php feature which will eventually also be the replacement for route annotations. So this invalides the argument
So to me there is no point in adding an alternative to annotations/attributes when you want to define routes near the controller code. And if you are not happy with attributes, you can implement your proposal in a custom route loader (even as a standalone bundle). No need to add this to core at this point IMO. |
I understand and respect your opinion. Certainly attributes should be cleaner than annotations. Still the RoutingConfigurator is pretty powerful and easy to use. No need to learn another syntax. Seems a shame not to encourage folks to use it outside of config/routing.php. And a potential shame not to be able to use the framework's tagging capability to identify routing files as opposed to searching by directory. But again, if the consensus is thumbs down then it's time to close this issue and move on. |
Container services can be tagged. But routing files are not services. I'm gonna close the issue. Thanks for sparking this discussion. |
…TheCat) This PR was merged into the 6.4 branch. Discussion ---------- [Routing][SecurityBundle] Add `LogoutRouteLoader` | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fix #50920 | License | MIT | Doc PR | symfony/symfony-docs#19000 #50920 is about avoiding for users to create logout routes. Given [we don’t want to allow bundles registering routes](#37786), I added a `LogoutRouteLoader` service bearing the `routing.route_loader` tag to be imported by the user. Such import could be added to the SecurityBundle recipe: ```yaml # config/routes/security.yaml logout: resource: security.route_loader.logout type: service ``` To invalidate routes when logout paths change, I stored them in a parameter so that the `ContainerParametersResourceChecker` can check the collection. Not sure if it’s okay or if a better way exists. Commits ------- 0a558d0 [SecurityBundle][Routing] Add `LogoutRouteLoader`
Like the event subscriber, a route subscriber would be able to define their own routes. No annotations needed and developers would have the power of the route configurator.
A file loader like the annotation loader could provide some automation. Maybe a compiler pass as well.
The text was updated successfully, but these errors were encountered: