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.
BlogController::clas -> BlogController::class
Thanks Javier for all your posts!
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?
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);