Connecting everything together with Routing.yml

📁 symfony

In this article we’re going to talk about Symfony’s routing system. Because you’ve read our comprehensive dissection, you already know that Symfony uses a front controller (you have read it… right?). This means that all URLs are serviced by a single script – typically contained in the “app.php” file. Obviously all our application logic, data models and presentation code isn’t contained in this one file, so how does Symfony know how to locate these in order to service individual requests? That’s where routing comes in.

A single “route” defines a mapping between one or more URLs of a certain format and a controller. A Symfony application will usually have multiple routes set-up, and by default these will be configured in the following file:

/app/config/routing.yml

Symfony also supports XML and PHP based routing files, which we can configure using the “/app/config/config.yml” file. This config file location and format are the defaults, so we’ll work with these. Personally I find the YAML format very easy to read and work with so I typically stick with it. Note that Symfony ends up parsing the routing configuration to a cached PHP file regardless of the format you use, so performance will be the same whether you use YAML, XML or PHP.

What does a route include?

  • An identifier: this is a (unique) name for the route that may be used when generating URLs for this route in controller or templating code.
  • A pattern: this is the string that the URL will be tested against. It may include “placeholder” values for dynamic URL parameters (see below for more information).
  • Defaults: this is used to specify default values for the attributes of a route. Note that the “_controller” field is required here to specify the controller to use. If you include placeholders in the pattern, you can make them optional by providing default values here.
  • Requirements (optional): it’s also possible to provide basic validation rules in the route. These are applied to the placeholders in the URL and will cause the route to be skipped if they do not match.

Now that we know what the standard components of a route are, we’re ready to see an live example.

In the simple example above, we can see a few things: the name of the route is “contact”, it matches the URL pattern “/contact” and the route only responds to HTTP GET requests (so form POSTs will not match the route). The “_controller” attribute will determine where requests will be sent that match the “pattern” and “requirements” of the route. It will use the logical name of the route, so in the example above, this will resolve to the “contactAction” action in the “Home” controller in “MyCompanyBundle”.

A more complex route can be seen in the example from the official Symfony documentation provided below:

There are a few important aspects to note in this route. The first is that we’re using dynamic parameters, such as {culture}, {year}, {title} and {\_format}. These values will match any value, so URLs such as these will work:

/articles/en/2012/article.html

The next important aspect to note is that we’re applying requirements to the parameters. These are regular expressions that check the following conditions:

  • “culture” is either “en” or “fr”
  • _format” is either “html” or “rss”
  • “year” is a numerical value.

If any of these conditions fail, the route will not match.

Also, you should notice that a default value for “_format” has been provided. This means that if this parameter is omitted, its value will be set to “html” by default.

The final thing to pay attention to is the special meaning of the underscore character in the parameter names. Parameters that start with this character have special meaning. In the above example, “_controller” defines the controller and action to map the URL route to. “_format” has a special meaning as well; it defines the response type.

Parameters in controllers

But how are the parameters in URL routes actually used? Well, if you look at the definition of AcmeDemoBundle:Article:show provided below, it should become obvious:

The parameters in the routing rules end up being provided as arguments to the action referenced by the routing rule. To make things super-simple, the names of the arguments will match the names defined in the pattern for the routing rule.

Importing external routing files

Often it makes sense to define routes at the bundle level instead of at the application level (especially if you intend to repackage your bundle for other projects or public use). We can do this by referencing an external “resource” in the “app/config/routing.yml” file, as such:

Note the “prefix” value. This means the routing rules within this file will only respond to URLs beginning with “mycompany”, and all rules within the file will be prepended with “mycompany”.

Provided we’ve configured the bundle such that it refers to “/src/MyCompany/SomeBundle”, this will include the file at the following location:

/src/MyCompany/SomeBundle/Resources/config/routing.yml

Wrap-up

That should cover the basics of Symfony routing. To learn more about the routing system, check out the Symfony documentation.