Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict Symfony 4 route to the "dev" environment

I'm using Symfony 4.1. I'm trying to create a route "/dev/import/{file}" which can only be accessed from within the 'dev' environment.

This answer for Symfony 2 suggests adding the route to routing_dev.yml or adding condition: "request.getScriptName() == '/app_dev.php'" to your route definition.

Neither option will work. In Symfony 4 there is no routing_dev.yml, it's now dev\routing_dev.YAML, which as far as I can tell is configuration only (i.e. you can not create routes there). Routes have to be defined in routes.yaml which will apply to all environments.

Adding the route to routes.yaml and applying the condition also does not work, as we're trying to match against the app_dev front controller, which has been removed in Symfony 4.

According to the Symfony 4 Documentation, conditions in routes only expose the Context and Request objects, neither of which (AFAICT) contain any information about the current environment. So, unless I am missing something, other conditions will not work either.

One possible, but (IMHO) inelegant solution would be to check that $_SERVER['APP_ENV'] = 'dev' in the controller and throw a RouteNotFoundException if it does not.

Rather than doing that, I would really like to either have the route simply not be available when not in 'dev', or define the route somehow to test for the 'dev' environment.

Any ideas on how to do that? Preferably using annotations.

like image 979
mcmurphy Avatar asked Aug 16 '18 17:08

mcmurphy


People also ask

How does Symfony routing work?

Symfony provides a Routing component which allows us, for a HTTP request/URL, to execute a specific function (also known as "Controller"). Note: Controllers must be a callable, for example: an anonymous function: $controller = function (Request $request) { return new Response() }; .

What is the default routing configuration file in Symfony application?

By default, the routing configuration file in a Symfony2 application is located at app/config/routing. yml. Like all configuration in Symfony2, you can also choose to use XML or PHP out of the box to configure routes.

What is Symfony annotation?

As you might know, Symfony2 uses annotations for Doctrine mapping information and validation configuration. Of course, it is entirely optional, and the same can be done with XML, YAML, or even PHP. But using annotations is convenient and allows you to define everything in the same file.


1 Answers

If you see the default configureRoutes() method on the generated Kernel class:

 protected function configureRoutes(RouteCollectionBuilder $routes)
    {
        $confDir = $this->getProjectDir().'/config';

        $routes->import($confDir.'/{routes}/*'.self::CONFIG_EXTS, '/', 'glob');
        $routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob');
        $routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob');
    }

The second import() call reads:

$routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob');

This will try to load routes defined under config/routes/[environment].

So if you create a dev folder there and add your routes there, those will only be loaded when on that specific environment. Logically that could also be used to define specific, specialized routes for other possible environments, although generally that wouldn't very particularly useful.

Of course, the generated configureRoutes() method belongs to your app, and you are free to tweak it to your needs if they are more esoteric. You could always rewrite it so it loaded the routes you wanted in the specific order you of your preference.


Apparently, you can also use 'conditions' (documented here) to define the same route but evaluate at runtime if it applies according to specific circumstances.:

E.g, as shown in this answer here using annotations:

/**
 * @Route("/my_route", condition="'dev' === '%kernel.environment%'")
 */

Or using YAML configuration, like in this answer:

my_route:
    path:       /my_route}
    defaults:   { _controller: App\Controller\MyRouteController }
    condition:  "%kernel.environment% === 'dev'"

Or using XML configuration:

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        https://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="my_route" path="/my_route" controller="App\Controller\MyRouteController">
        <condition>%kernel.environment% === 'dev'</condition>
    </route>
</routes>
like image 179
yivi Avatar answered Oct 08 '22 07:10

yivi