The PSR-15 face of Polaris for PHP: a router over the endpoint manifest, the ordered middleware stack (client context, rate limits, bearer and MFA-ticket authentication, step-up, denylist, authorization) and the request handler that runs the endpoints. It works with any PSR-15 host: Slim, Mezzio, or a framework through its PSR-7 bridge.
Install
composer require polaris/psr15This brings polaris/core; you also need a PSR-17 response factory (nyholm/psr7,
laminas/laminas-diactoros, slim/psr7, …).
Use
use Polaris\Psr15\Pipeline;
$pipeline = new Pipeline($polaris->graph(), $responseFactory, pathPrefix: '/');
$pipeline->middleware(); // list<MiddlewareInterface>, in execution order$pipeline->handler(); // RequestHandlerInterface serving every route of the manifest$pipeline->handle($request); // or run the whole stack yourselfOn Slim, for instance (the full demo is
examples/slim):
foreach (array_reverse($pipeline->middleware()) as $middleware) { // Slim runs the last-added first $app->add($middleware);}$app->any('/{path:.*}', fn($request) => $pipeline->handler()->handle($request));The middleware reads each route’s policy (auth, rate_limit, step_up, required
permissions) from the manifest, so nothing is configured per route. Your own middleware can
read the request attributes named in Polaris\Http\Attributes: TOKEN (the verified token),
IP_ADDRESS, USER_AGENT.
License
MIT.
The Slim bootstrap
The whole integration, examples/slim/src/bootstrap.php:
<?php
declare(strict_types=1);
use Polaris\Config\EnvironmentConfig;use Polaris\Pdo\PdoAdapter;use Polaris\Polaris;use Polaris\Psr15\Pipeline;use Polaris\Wiring\Config;use PolarisDemo\Dispatcher;use PolarisDemo\Env;use PolarisDemo\FileMailer;use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Slim\Factory\AppFactory;use Slim\Psr7\Factory\ResponseFactory;
$root = dirname(__DIR__);require $root . '/vendor/autoload.php';
Env::load($root);
$dsn = Env::require('POLARIS_DSN');$pdo = new PDO(str_starts_with($dsn, 'sqlite:') ? 'sqlite:' . Env::sqlitePath($root, $dsn) : $dsn);$pdo->exec('PRAGMA foreign_keys = ON');
$dispatcher = new Dispatcher();$polaris = Polaris::create(new Config( secrets: EnvironmentConfig::secrets(), auth: EnvironmentConfig::auth(), database: new PdoAdapter($pdo), mailer: new FileMailer($root . '/var/mail.log'), dispatcher: $dispatcher,));foreach ($polaris->listeners() as $listener) { $dispatcher->listen($listener);}
$pipeline = new Pipeline($polaris->graph(), new ResponseFactory());
$app = AppFactory::create();$app->addBodyParsingMiddleware();// Slim runs the last-added middleware first; Polaris lists its stack in execution order.foreach (array_reverse($pipeline->middleware()) as $middleware) { $app->add($middleware);}$app->any('/{path:.*}', static fn(ServerRequestInterface $request): ResponseInterface => $pipeline->handler()->handle($request));
return $app;