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!
Thank for sharing. The drawback here is that the env var will be read at compile time, which kinda defeat its purpose. Good news, Symfony 5.1 will provide a solution, you could mention it in your article: https://t.co/oFRuk3RP19
— Nicolas Grekas (@nicolasgrekas) February 24, 2020
Thanks to Nicolas Grekas for pointing this out.