When I define an "after" middleware to a single route (i.e. it works with the chain's response object), and I have a router-wide middleware in place that returns a response, the per-route middleware is never invoked from the looks of it (or then I'm doing something stupid).
Small example that fails on my end. Packages required are this router package, and zend/diactoros, along with the PSR interfaces.
<?php
use Psr\Http\Message\ResponseInterface as RI;
use Psr\Http\Message\ServerRequestInterface as SRI;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface as RHI;
use Sunrise\Http\Router\RouteCollection;
use Sunrise\Http\Router\Router;
use Zend\Diactoros\Response\HtmlResponse;
use Zend\Diactoros\ServerRequestFactory;
include dirname(__DIR__) . '/vendor/autoload.php';
function callback_action(SRI $req) : RI
{
return new HtmlResponse('foo bar');
}
class MyRouteMiddleware implements MiddlewareInterface
{
// this method is never called
// you can even call `die` inside it and nothing happens
public function process(SRI $req, RHI $handler) : RI
{
$response = $handler->handle($req);
return $response->withHeader('X-Foo', 'bar');
}
}
class MyAppMiddleware implements MiddlewareInterface
{
public function process(SRI $req, RHI $handler) : RI
{
// this just takes the route "handler" and calls it to return
// a response see callback_action($req)
$action_callable = $req->getAttribute('@route');
return $action_callable($req);
}
}
// first create a router, and add an "app-wide" middleware to it
$router = new Router();
$router->addMiddleware(new MyAppMiddleware());
// then create individual route, and add a per-route middleware to it
$routes = new RouteCollection();
$routes->get('\\callback_action', '/')
->addMiddleware(new MyRouteMiddleware());
$router->addRoutes($routes);
$request = ServerRequestFactory::fromGlobals();
// dispatch via the router
$response = $router->handle($request);
assert(trim($response->getBody()) === 'foo bar'); // this does not fail
assert($response->hasHeader('X-Foo')); // this fails
Please do say if I'm doing something wrong here, maybe I'm just blind form debugging this and am missing a stupid mistake somewhere.