The ModularRouter class combines the power of the Symfony router with the flexibility of the ModularRouting component. A router is an all-in-one package that simplifies the use the of routing in a project. The Symfony Router class was developed to handle static route definitions with a fixed set of metadata and is not suited for dynamically generated routes. The ModularRouter class uses instances of ProdiverInterface and MetadataFactoryInterface to map a request to a module and to load the relevant routing metadata respectively.

In order to use the router you need to set up several dependencies:

Creating the module class

The goal of this component is to map similar requests to different Route definitions based on a Module instance associated with the request. The Module instance holds the reference to a set of routing metadata. Your first tasks are to create a Module class and to initialize a ModuleManagerInterface object. Your Module class can act however you want it to, so add any properties or methods you need for your project.

To create a class that acts a module, it needs to implement ModuleInterface. You can also choose to extend the base Module class provided by this component. In the following section you'll see an example of how your Module class should look if you're using the Doctrine ORM.

Doctrine ORM Module class

// src/Application/Entity/Module.php

namespace Application\Entity;

use Doctrine\ORM\Mapping as ORM;
use Harmony\Component\ModularRouting\Model\Module as BaseModule;

 * @ORM\Entity
 * @ORM\Table(name="module")
class Module extends BaseModule
     * @var integer
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
    protected $id;

     * @var string
     * @ORM\Column(name="modular_type", type="string", length=255)
    protected $modularType;

     * Get id
     * @return integer
    public function getId()
        return $this->id;

     * Get modular identity
     * @return mixed
    public function getModularIdentity()
        return $this->getId();

    // custom methods...

Initializing a module manager

To manage the modules in your project, a provider is encouraged to use an instance of ModuleManagerInterface. These are some examples of managers included in this component:

// Doctrine ORM
use Harmony\Component\ModularRouting\Doctrine\ModuleManager;

$moduleManager = new ModuleManager($entityManager, 'Application\Entity\Module');

// Static
use Harmony\Component\ModularRouting\StaticModuleManager;

$moduleManager = new StaticModuleManager;

Setting up a provider

Providers are the backbone of the ModularRouting component and are responsible for matching the request to a module using the module manager. Each provider can define its own behaviour when matching for a module, this doesn't have to involve the This component currently includes a single provider:


To learn how to create your own provider, check out the Creating a custom provider section of this documentation.

It is up to the provider to choose how to load the route definitions from the metadata it retrieves from the metadata factory. The providers included in this component use a loader from the Symfony Routing component as explained in the Symfony documentation. A prefix is added to the routes to accommodate for the matching strategy.

This is an example of how to set up the SegmentProvider included in this component:

use Harmony\Component\ModularRouting\Provider\SegmentProvider;

$provider = new SegmentProvider($moduleManager);

Setting up a metadata factory

The MetadataFactory class loads and returns ModuleMetadata objects from a resource using a loader instance.

The ModularRouting component comes with a number of loader classes, each giving you the ability to load metadata from an external file of some format. Each loader expects a FileLocator instance as the constructor argument. If a file is found, the loader returns an array with the metadata.

If you want to use YAML to define metadata about your modules, you can use the following code, assuming that your metadata file is in the same directory:

use Symfony\Component\Config\FileLocator;
use Harmony\Component\ModularRouting\Metadata\Loader\YamlFileLoader as MetadataYamlFileLoader;

// look inside *this* directory
$locator = new FileLocator([__DIR__]);
$metadataLoader = new MetadataYamlFileLoader($locator);

Now that you have a loader, you can create a file containing the metadata:

# modules.yml
    name: "Foo Module"
    type: "acme_foo"
        - { resource: "app/config/routing/foo.yml", type: "yaml" }

    name: "Bar Module"
    type: "acme_bar"
        - { resource: "app/config/routing/bar.yml", type: "yaml" }

More information on loaders included in this component is available in the Defining metadata section.

Since the metadata can be different depending on the request, the routing resources of a module are only loaded when the project requests the metadata for that specific module. To do this, the MetadataFactory uses a second loader to load the routing resources:

use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader as RoutingYamlFileLoader;

// look inside *this* directory
$locator = new FileLocator([__DIR__]);
$routingLoader = new RoutingYamlFileLoader($locator);

With these loaders set up, you're ready to load the metadata defined in the metadata file:

use Harmony\Component\ModularRouting\Metadata\MetadataFactory;

$metadataFactory = new MetadataFactory($metadataLoader, $routingLoader, 'modules.yml', 'yaml');

Using the router

The ModularRouter class is similar to the Router class from the Symfony Routing component but delegates the loading of route definitions to a metadata factory as explained in the previous section. This allows the router to load a RouteCollection object based on the routing metadata of the module associated with the request path. In addition, an array of options is used to configure the router. This is what a basic implantation of the ModularRouter class would look like:

use Harmony\Component\ModularRouting\ModularRouter;
use Symfony\Component\Routing\RequestContext;

$router = new ModularRouter(
    ['cache_dir' => __DIR__ . '/cache'],
    new RequestContext('/')


With the cache_dir option you can enable route caching (if you provide a path) or disable caching (if it's set to null). The caching is done automatically in the background if you want to use it.

Using a route prefix

The ModularRouter class allows a route prefix to be set for all modular routes. This is useful if your project is configured with multiple routers.


It's also possible to create a route prefix with placeholders:

    '/{prefix}/module', // path
    [], // default values
    ['prefix' => '[\w]{4}'] // requirements

This page was last updated on 16 Jul 2017, at 15:50.