← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

PSR-15: HTTP Handlers & Middleware

style PHP 7.0+ Intermediate

Also Known As

PSR-15 HTTP middleware MiddlewareInterface RequestHandlerInterface

TL;DR

Defines RequestHandlerInterface and MiddlewareInterface for composable, framework-agnostic HTTP middleware pipelines.

Explanation

PSR-15 builds on PSR-7 to define two interfaces: RequestHandlerInterface (handle(ServerRequestInterface): ResponseInterface — the final handler) and MiddlewareInterface (process(ServerRequestInterface, RequestHandlerInterface): ResponseInterface — wraps a handler). Middleware compose as nested decorators: authentication middleware wraps routing middleware wraps the application handler. This enables mixing middleware from different libraries in any framework supporting PSR-15. Relay, Slim, and Laminas Mezzio implement PSR-15 dispatch. Each middleware can short-circuit (return a response without calling next) or pass through.

Common Misconception

PSR-15 middleware is the same concept as Laravel middleware. Laravel middleware predates PSR-15 and uses a different interface — PSR-15 is framework-agnostic and used by Slim, Laminas, and others. Laravel has PSR-15 adapter packages but does not use it natively.

Why It Matters

PSR-15 defines HTTP server middleware and request handler interfaces — middleware components from different libraries can be composed into a pipeline without framework lock-in.

Common Mistakes

  • Middleware that modifies the request but does not pass the modified request to the handler.
  • Not returning the response from $handler->handle() — middleware that forgets to return breaks the chain.
  • Too much logic in a single middleware — each middleware should handle one cross-cutting concern.
  • Not understanding that middleware wraps the handler — the handler is called inside the middleware, not after.

Code Examples

✗ Vulnerable
// Middleware that forgets to return the response:
class AuthMiddleware implements MiddlewareInterface {
    public function process(ServerRequestInterface $req, RequestHandlerInterface $handler): ResponseInterface {
        if (!$this->auth->check($req)) {
            return new Response(401);
        }
        $handler->handle($req); // Bug: response not returned!
        // Fix: return $handler->handle($req);
    }
}
✓ Fixed
// PSR-15 HTTP Server Request Handlers

// Handler interface — processes a request and returns a response
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

class OrderHandler implements RequestHandlerInterface {
    public function handle(ServerRequestInterface \$request): ResponseInterface {
        \$body = json_decode((string) \$request->getBody(), true);
        \$order = \$this->orderService->place(\$body);
        return \$this->responseFactory->createResponse(201)
            ->withHeader('Content-Type', 'application/json')
            ->withBody(\$this->streamFactory->createStream(json_encode(\$order)));
    }
}

// Middleware interface — wraps handlers
use Psr\Http\Server\MiddlewareInterface;

class AuthMiddleware implements MiddlewareInterface {
    public function process(ServerRequestInterface \$request, RequestHandlerInterface \$handler): ResponseInterface {
        if (!\$this->isAuthenticated(\$request)) return \$this->unauthorized();
        return \$handler->handle(\$request);
    }
}

Added 15 Mar 2026
Edited 22 Mar 2026
Views 15
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 2 pings S 0 pings M 0 pings T 1 ping W 2 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S
No pings yet today
No pings yesterday
Amazonbot 6 Google 4 Perplexity 3 ChatGPT 2 Ahrefs 1
crawler 12 crawler_json 4
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Build middleware pipelines using MiddlewareInterface — each middleware calls $handler->handle($request) to pass to the next; this enables reusable authentication, logging, and rate-limiting middleware
📦 Applies To
PHP 7.0+ web api
🔗 Prerequisites
🔍 Detection Hints
Middleware tightly coupled to specific framework; no reusable middleware between Laravel and Slim; authentication logic not extractable as middleware
Auto-detectable: ✓ Yes phpstan deptrac
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: Medium ✗ Manual fix Fix: Medium Context: File Tests: Update

✓ schema.org compliant