Middleware
Middleware follows the onion model. Each middleware receives the Request and a $next callable:
class TimingMiddleware
{
public function handle(Request $request, callable $next): Response
{
$start = microtime(true);
$response = $next($request);
$elapsed = round((microtime(true) - $start) * 1000, 2);
return $response->withHeader('X-Response-Time', "{$elapsed}ms");
}
}
Registering Middleware
// Global middleware (all routes)
$app->addMiddleware(new CorsMiddleware());
$app->addMiddleware(new RateLimitMiddleware(maxRequests: 100, windowSeconds: 60));
// Route group middleware
$router->group('/api', function (Router $r) {
// routes here
}, middleware: ['AuthMiddleware']);
// Per-route middleware
$router->get('/admin', $handler, middleware: ['AdminOnly']);
Built-in Middleware
CORS
$cors = new CorsMiddleware(
allowedOrigins: ['https://myapp.com', 'https://staging.myapp.com'],
allowedMethods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
maxAge: 86400,
);
$app->addMiddleware($cors);
Rate Limiting
$limiter = new RateLimitMiddleware(
maxRequests: 60, // requests per window
windowSeconds: 60, // window size
);
$app->addMiddleware($limiter);
// Returns 429 Too Many Requests when exceeded, with X-RateLimit-* headers
Authentication (see Authentication section)
Role/Permission (see Authorization section)