Slim 4 : Hiding routes at request time

I’m finally converting a Slim 2 project to Slim 4, and I’m looking for suggestions on hiding routes for particular requests.

Due to the nature of the project and all the legacy code, I’m keeping the controller classes and am providing a static routes method that takes an App to initially configure the routes for that controller.

Under Slim 2, the constructor had all the routes and used closures. I’m looking forward to getting rid of that.

However, one of the things we would do, for particular controllers that might require a logged in user is check the session at the start of the session, and if things were not looking right, then we would simply not set up those routes (i.e. return immediately from the controller so the routes would never get created).

Under Slim 4, I might imagine this method doesn’t work so well, considering all the routes are set up before we even set up middleware or start processing a request.

However, one thing I was considering is putting something into the controller constructor, so that when a route is found and the controller class is instantiated, those catch all checks can be done the, and if the controller is not for you because you don’t have a logged in session, etc, then I could throw a HttpNotFoundException.

This assumes that the controller class is only created once an appropriate route has been configured, and controller instances are not shared between requests. I’m new to DI containers in PHP, but have worked with DI containers in Java many moons ago with Spring Framework, and their controller instances were shared between requests.

Also, in my project, I’m controllers are accepting the ContainerInterface argument, rather than wiring up in the container. Mostly because the controllers are legacy, have a lot of routes, and making the constructor sig use any or all container instances that it requires across so many routes would look ugly and be overkill. If I had action classes instead, then container wiring would be the better way to go.

Can anyone with a bit more knowledge in working with Slim 4 than me (it’s only been a few days) see this as a plausible solution?

I found my first hurdle. The HttpNotFoundException requires a request, which is only available in the route action or as a part of middleware.

For whole of controller blocks, putting an method check at the start of each route seems smelly, and might lend itself better to middleware. Conversely, implementing that in middleware for specific controllers splits that requirement out of the controller.

I already have Auth middleware that will only let specific URIs through if you don’t have a session, so maybe I should just trust that.

It just occurred to me that I could add the middleware to the route directly, as a group or as individual entries, and I can configure which enabled area(s) a filter should be applied for.

$app->get('/secret', [self::class, 'secret'])
    ->add(new EnabledAreaMiddleware("area51"));

This gets it handled in middleware that doesn’t need to know about the controller or route, specifically, and the limitation stays with the route.

Seems I’ve done a sideways leap of thought, as I had another scenario where I wanted to limit routes based on enabled areas that are determined at runtime. More related to access than auth.

Do you know about Middleware?

Please consider reading the documentation and you can also use skeleton to get started.

To understand Middleware better, you can see the source of my Middleware here: