Conditional Routing in Symfony using ENV Vars

I recently wanted to be able to control whether a route was available based on an environment variable, in dev I wanted it available, but in production I wanted it turned off (for now). I like using feature flags and environment variables to toggle things on and off, and thought I'd write up how I did it here.

To do this, we make use of a number of features in Symfony:

Parameters

First, I a parameter in the config from an environment variable. Then I need to make sure there's a default value to fall back to if the environment variable isn't found.

In my config/services.yaml file I have:

parameters:
    contact_enabled: '%env(default:default_contact_enabled:bool:CONTACT_ENABLED)%'
    default_contact_enabled: false

This falls back to the default_contact_enabled value if the environment variable isn't set in the environment it's currently running in.

Routing

We then use a condition on the route and the expression syntax to pull the contact_enabled value from the configuration, and if it's truthy, the route will be enabled.

In my config/routes.yaml file:

contact:
    path: /contact
    controller: App\Action\Contact
    condition: "%contact_enabled% == true"

With this, if the environment variable CONTACT_ENABLED is set to 1, then the route is registered and works. But if it's not set, or it's set to 0 it will 404.

Updates

Mon 24th Feb 2020:

The above will mean that the environment variable will be read at compile time in Symfony, so if you changed it, you'd need to re-compile the app. In Symfony 5.1 we'll be able to use env() in routing conditions!

Thanks to Nicolas Grekas for pointing this out.