Middleware pipelines - markstory/cakephp GitHub Wiki

When this was last brought up Jose-Lorenzo wanted middleware integrated into routing. I originally thought this might be really hard, and it still might be, but here is a rough idea of what the API could be:

  • The Cake\Routing\Middleware\RoutingMiddleware class would take an Application as a parameter. If that parameter is provided, the middleware will invoke the routing hook method on the application.
  • The Application::routing() method would provide an object wrapper for config/routes.php like Application::bootstrap() provides for config/bootstrap.php. Inside this method routes could be connected, much as they are today.

By default the routing hook would simply include config/routes.php, but it could be overridden as well.

An example of the routing hook and the routing middleware in action would be:

function routing($routes)
{
    // Register middleware, for use in routing scopes
    $routes->registerMiddleware('auth', new AuthenticationMiddleware(...))
        ->registerMiddleware('cookies', new EncryptedCookieMiddleware(...))
        ->registerMiddleware('csrf', new CsrfMiddleware(...));
        ->registerMiddleware('cors', new CorsMiddleware(...));

    // Create a routing scope (as you do today)
    $routes->scope('/api', function ($routes) {
        // Enable middleware
        $routes->middleware('csrf', 'cors', 'auth');
        $routes->connect('/ping', ['controller' => 'Pings']);
    });

    $routes->scope('/bookmarks', function ($routes) {
        // Enable middleware
        $routes->middleware('csrf', 'cookies', 'auth');
        $routes->connect('/bookmarks/:action', ['controller' => 'Bookmarks']);
    });
}

Detailed Steps

  • RouteBuilder would be updated to have new methods for registering middleware into the RouteCollection.
  • After routes are matched, RoutingMiddleware could fetch the middleware for a given URL similar to how we do scope matching today. $next = Router::getMiddlewareForRequest($request, $next);
  • Middleware would be matched by the registered scopes.
  • Once found, middleware objects would be added to a new MiddlewareStack object.
  • The $next parameter would be appended to the MiddlewareStack containing route specific middleware.
  • RoutingMiddleware would invoke $next as it currently does.