New in Symfony 6.4: FQCN-based Routes
October 25, 2023 • Published by Javier Eguiluz
Symfony 6.4 is backed by:
In Symfony applications, the routing system requires each route to have a name, which is an arbitrary string that uniquely identifies the route. This name is later used for example when generating URLs from route definitions.
The route name is usually defined explicitly by developers when adding routes
(e.g. via the name
option of the #[Route]
attribute):
1 2 3 4 5 6 7 8 9 10 11 12 13
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
final class BlogController extends AbstractController
{
#[Route('/blog', name: 'blog_index')]
public function index(): Response
{
// ...
}
}
If you don't define the route name explicitly, Symfony generates an automatic
route name based on the FQCN (fully-qualified class name) of the controller and
the action method name. In the above example, the automatic route name would be
app_blog_index
.
Automatic route names work because the combination of the controller's FQCN and the action method name is guaranteed to be unique in the application. That's why in Symfony 6.4 we're improving this feature to introduce automatic routes based on controllers' FQCN.
If a controller method is associated to a single route (remember that Symfony allows
associating the same controller method to multiple routes) Symfony will create
a route alias following the pattern <Controller FQCN>::<method name>
.
In the previous example, the index()
method is associated both to the explicit
blog_index
route name and to the 'App\Controller\BlogController::index'
route name created automatically by Symfony:
1 2 3 4 5 6 7 8
use App\Controller\BlogController;
// ...
// generate the URL using the explicit route name
$url = $this->urlGenerator->generate('blog_index');
// generate the URL using the route alias created by Symfony based on the FQCN
$url = $this->urlGenerator->generate(BlogController::class.'::index');
If you use invokable controllers, which are controller classes that define PHP's
__invoke()
magic method, the route alias is even simpler because you don't
need to add the method name:
1 2 3 4 5 6 7 8 9 10 11 12 13
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/blog', name: 'blog_index')]
final class BlogController extends AbstractController
{
public function __invoke(): Response
{
// ...
}
}
The URL pointing to this method can be generated with the blog_index
explicit
route name and with the BlogController::class
route alias.
Related to this feature, in the Pull Request #50109 we improved the output of
the debug:router
command so you can see the route aliases too.
This feature is completely optional, so you can keep using and defining routes as you always did. However, this new route alias will allow developers using invokable and single-route controllers to avoid using "magic strings" to define route names.
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
Small typo spotted:
BlogController::clas -> BlogController::class
Thanks Javier for all your posts!
Good catch! It's fixed now. Thanks a lot Hugo.
Very nice addition, thanks a lot!
Is this a breaking change for applications that rely on the auto generated names?
Good feature. It’s very good for my case because I always use one action in the controller
@Jeroen I've reworded the blog post a bit to explain more clearly that the new FQCN-based routes are created as route aliases, so the previous route names (either explicitly set by you or automatically created by Symfony) keep working.
"In addition to invokable controllers, this feature also works for controllers that only define a single route. In the following example, the generated route alias is App\Controller\BlogController::index:"
As your exemple does have a function name for controllers with single name, why wouldn't it work multiple functions like BlogController::show, BlogController::new?
@Philippe we've reworded the post to better explain this. You are right and this feature works for all methods that define a single route.
That's super!
Maybe we can find a way to point to a function: // importing a function use function My\Full\functionName;
// aliasing a function use function My\Full\functionName as func;
// generate the URL using the route alias created by Symfony based on the FQCN & function name: $url = $this->urlGenerator->generate(functionName); $url = $this->urlGenerator->generate(func);
Automating a naming convention i was already using. Love it!