Open
Description
Hello
This framework is really great and I am very glad to be using it.
However, one feature that I think might be missing is middleware. I have managed to implement a very simple solution, but it is kind of sloppy. Here is an example of my implementation:
namespace Example\Middleware;
abstract class RouteLayer {
function before($app, $context) { }
function after($app, $context) { }
}
abstract class RouteHandler {
private $layers;
function __construct($layers = array()) {
$this->layers = $layers;
}
function execute($app, ...$routeParams) {
$context = array(); //holds any data used by the layers, route handler implementation, or twig templates
$context['routeParams'] = $routeParams;
//loop through the layer pipe forwards handling entrance methods
for ($i = 0; $i < count($this->layers); $i++) {
$newContext = $this->layers[$i]->before($app, $context);
$context = isset($newContext) ? $newContext : $context; //just in case a modified context isn't returned by implementors
}
//handle the main route code
$newContext = $this->handle($app, $context);
$context = isset($newContext) ? $newContext : $context; //just in case a modified context isn't returned by implementors
//loop through the layer pipe backwards handling exit methods
for ($i = count($this->layers) - 1; $i >= 0 ; $i--) {
$newContext = $this->layers[$i]->after($app, $context);
$context = isset($newContext) ? $newContext : $context; //just in case a modified context isn't returned by implementors
}
}
abstract protected function handle($app, $context);
}
class ExampleRoute extends RouteHandler {
function __construct() {
//example layers not yet written
$layers = [
new \Example\Middleware\LoggingLayer(),
new \Example\Middleware\AuthenticationLayer(), //redirects to login if unauthenticated
new \Example\Middleware\AuthorizationLayer(), //checks if user has necessary privileges for the route's action
new \Example\Middleware\ThrottleLayer(), //to be used on routes which write to db
];
parent::__construct($layers);
}
function handle($app, $context) {
echo $app->view('example.html', $context); //context has everything needed for twig template
}
}
$app->get('/example/:id/:verb', function($app, $id, $verb) { //uses a closure to cause lazy class autoloading of route handlers/layers
(new \Example\ExampleRoute())->execute($app, $id, $verb);
});
It may not be pretty but it works. I was wondering, do you think such features have a place in this framework? Or perhaps you prefer another solution or library? It seems like relayphp isn't appropriate for use with this framework, and the other middleware libs are also tailored for other frameworks...