Polaris for PHP · PSR-15 Slim, Mezzio, any PSR-15 host

polaris/psr15

packagist.org/packages/polaris/psr15 examples/slim /docs/php/psr15

Rendered from univeros/polaris-core at v0.1.0 · View source

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

Terminal window
composer require polaris/psr15

This 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 yourself

On 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;