When you setup a routes to show, create, edit or delete an album for example, inside your routing setup you might have something like this:
$app->get('/show', ShowAlbumHandler::class, 'show');
$app->get('/edit', EditAlbumHandler::class, 'edit');
$app->get('/delete', DeleteAlbumHandler::class, 'delete');
As things progress and you want to authenticate users of those routes, you’d need something like:
$app->get('/show', [OnlyAuthenticated::class, ShowAlbumHandler::class], 'show');
$app->get('/edit', [OnlyAuthenticated::class, EditAlbumHandler::class], 'edit');
$app->get('/delete', [OnlyAuthenticated::class, DeleteAlbumHandler::class], 'delete');
Perhaps later on you also want to restrict the IP address, but instead of prepending another middleware to all 3 routes, such as IPRestrictMiddleware::class
, you create a pipeline something like this:
use Laminas\Stratigility\MiddlewarePipeInterface;
use Mezzio\MiddlewareFactory;
final class SomePipelineFactory {
public function __invoke(ContainerInterface $container) : MiddlewarePipeInterface
{
$factory = $container->get(MiddlewareFactory::class);
return $factory->pipeline([
IPRestrictMiddleware::class,
OnlyAuthenticated::class,
]);
}
}
I personally like to create marker interfaces for specific pipelines that look something like:
use Laminas\Stratigility\MiddlewarePipeInterface;
interface SomePipeline extends MiddlewarePipeInterface
{
}
… so that in config I have
'dependencies' => [
'factories' => [
SomePipeline::class => SomePipelineFactory::class,
],
],
Finally, in my routing setup, I can say:
$app->get('/show', [SomePipeline::class, ShowAlbumHandler::class], 'show');
$app->get('/edit', [SomePipeline::class, EditAlbumHandler::class], 'edit');
$app->get('/delete', [SomePipeline::class, DeleteAlbumHandler::class], 'delete');
So, that’s what I meant - A convenient way of referring to and composing collections of middleware when you have multiple uses for the same functionality.