Modular Routing in Symfony

This post is deprecated since June 2017
I have deprecated this package, because of feedback that it is not useful and low download rates (under 2 000 in 2 years).

Modular routing in Symfony is bounded to routing.yml. Adding few lines for each new module can create large mess. Can we make it bit simpler? Sure we do and I will show you how.

Let's say you have fairly standalone module or package and you want to add its routes as simple as:

// app/AppKernel.php

final class AppKernel extends Kernel
{
    public function registerBundles(): array
    {
        $bundles = [
            new App\MeetupModule\AppMeetupModuleBundle(),
            // ...
        ];
    }
}

So, what you can do?


Wow, so many options!
Wow, so many options!


As Matthias Noback wrote 4 years ago, in Symfony 1 you could use routing.load_configuration event to do this, but it was removed in Symfony 2. As a replacement, Matthias suggests creating custom Route Loader. It's the best solution so far I used before.

But I'm older and more lazy now so I tried to find a simpler way.

Warning!
If you prefer YAML, XML or PHP definition, good news - continue.
In case you use @Route annotation, following solution won't help you.

Load your routes in 1 method

Routes are usually in form of a simple array with urlcontroller records.

What if loading of this simple array could be done via simple service? Something as simple as:

use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

public function getRouteCollection(): RouteCollection
{
    return $this->loadRouteCollectionFromFile(__DIR__ . '/routes.yml');

    // OR xml
    return $this->loadRouteCollectionFromFile(__DIR__ . '/routes.xml');

    // OR even multiple files
    return $this->loadRouteCollectionFromFiles([
        __DIR__ . '/front_routes.yml',
        __DIR__ . '/admin_routes.yml'
    ]);

    // OR pure PHP with some tweaks
    $routeCollection = new RouteCollection();
    $routeCollection->add('my_route', new Route('/hello'));

    return $routeCollection;
}

Load your routes in modular way in 4 steps

All those options above are available in Symfony, thanks to Symplify\ModularRouting package.

Let's try it together.

1. Install package

composer require symplify/modular-routing

2. Register bundles

// app/AppKernel.php
final class AppKernel extends Kernel
{
    public function registerBundles(): array
    {
        return [
            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
            new Symfony\Cmf\Bundle\RoutingBundle\CmfRoutingBundle(),
            new Symplify\ModularRouting\SymplifyModularRoutingBundle(),
            // ...
        ];
    }
}

3. Create services to load your YAML file

// src/SomeBundle/Routing/SomeRouteCollectionProvider.php
namespace SomeBundle\Routing;

use Symfony\Component\Routing\RouteCollection;
use Symplify\ModularRouting\Routing\AbstractRouteCollectionProvider;

final class SomeRouteCollectionProvider extends AbstractRouteCollectionProvider
{
    public function getRouteCollection(): RouteCollection
    {
        # routes.yml is the file, where all your routes are located
        return $this->loadRouteCollectionFromFile(__DIR__ . '/routes.yml');
    }
}

4. Register it as a service to your module

# src/SomeBundle/Resources/config/services.yml
services:
    SomeBundle\Routing\SomeRouteCollectionProvider: ~

And that's it! Now all routes are loaded along with your bundle registration.

For further use, just check Readme for Symplify/ModularRouting.



What have you learned today?

If you have some questions or tips for how to make loading of routes simpler, just let me know below.

Happy coding!