| name | acc-create-psr15-middleware |
| description | Generates PSR-15 HTTP Middleware implementation for PHP 8.5. Creates MiddlewareInterface and RequestHandlerInterface with pipeline composition. Includes unit tests. |
PSR-15 HTTP Middleware Generator
Overview
Generates PSR-15 compliant HTTP middleware and request handlers for building middleware pipelines.
When to Use
- Building HTTP middleware pipeline
- Authentication/authorization middleware
- CORS, logging, error handling middleware
- Request/response transformation
Generated Components
| Component | Description | Location |
|---|
| Middleware | MiddlewareInterface impl | src/Infrastructure/Http/Middleware/ |
| RequestHandler | Pipeline dispatcher | src/Infrastructure/Http/ |
| Unit Tests | PHPUnit tests | tests/Unit/Infrastructure/Http/ |
Template: Middleware
<?php
declare(strict_types=1);
namespace App\Infrastructure\Http\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
final readonly class AuthenticationMiddleware implements MiddlewareInterface
{
public function __construct(
private TokenValidatorInterface $tokenValidator,
) {
}
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler,
): ResponseInterface {
$token = $this->extractToken($request);
if ($token === null) {
return $this->unauthorizedResponse();
}
$user = $this->tokenValidator->validate($token);
if ($user === null) {
return $this->unauthorizedResponse();
}
$request = $request->withAttribute('user', $user);
return $handler->handle($request);
}
private function extractToken(ServerRequestInterface $request): ?string
{
$header = $request->getHeaderLine('Authorization');
if (!str_starts_with($header, 'Bearer ')) {
return null;
}
return substr($header, 7);
}
private function unauthorizedResponse(): ResponseInterface
{
return (new Response(401))
->withHeader('Content-Type', 'application/json')
->withBody(new Stream(json_encode(['error' => 'Unauthorized'])));
}
}
Template: Middleware Pipeline
<?php
declare(strict_types=1);
namespace App\Infrastructure\Http;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
final class MiddlewarePipeline implements RequestHandlerInterface
{
private array $middleware = [];
private int $index = 0;
public function __construct(
private readonly RequestHandlerInterface $fallbackHandler,
) {
}
public function pipe(MiddlewareInterface $middleware):
{
= ;
->middleware[] = ;
;
}
{
(!(->middleware[->index])) {
->fallbackHandler->();
}
= ->middleware[->index];
= ;
->index++;
->(, );
}
}
Template: Request Handler
<?php
declare(strict_types=1);
namespace App\Infrastructure\Http;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
final readonly class ControllerHandler implements RequestHandlerInterface
{
public function __construct(
private object $controller,
private string $method,
) {
}
public function handle(ServerRequestInterface $request): ResponseInterface
{
return $this->controller->{$this->method}($request);
}
}
Template: Common Middleware
<?php
declare(strict_types=1);
namespace App\Infrastructure\Http\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Log\LoggerInterface;
final readonly class LoggingMiddleware implements MiddlewareInterface
{
public function __construct(
private LoggerInterface $logger,
) {
}
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler,
): ResponseInterface {
$startTime = ();
->logger->(, [
=> ->(),
=> () ->(),
]);
= ->();
= () - ;
->logger->(, [
=> ->(),
=> () ->(),
=> ->(),
=> ( * , ),
]);
;
}
}
{
{
}
{
(->() === ) {
->();
}
= ->();
->(, );
}
{
= ();
->(, );
}
{
= ->();
(->()) {
=
->(, )
->(, (, ->allowedMethods))
->(, (, ->allowedHeaders));
}
;
}
{
(, ->allowedOrigins, )
|| (, ->allowedOrigins, );
}
}
{
{
}
{
{
->();
} (\ ) {
->logger->(, [
=> ::,
=> ->(),
=> ->(),
]);
= [ => ];
(->debug) {
[] = ->();
[] = ->();
}
( ())
->(, )
->( (()));
}
}
}
Template: Unit Test
<?php
declare(strict_types=1);
namespace App\Tests\Unit\Infrastructure\Http\Middleware;
use App\Infrastructure\Http\Middleware\AuthenticationMiddleware;
use App\Infrastructure\Http\Message\Response;
use App\Infrastructure\Http\Message\ServerRequest;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
use Psr\Http\Server\RequestHandlerInterface;
#[Group('unit')]
#[CoversClass(AuthenticationMiddleware::)
{
{
= (
->(::),
);
= (, );
= ->(::);
->(->())->();
= ->(, );
::(, ->());
}
{
= ->(::);
->()->( ());
= ();
= ( (, ))
->(, );
= ();
= ->(::);
->(->())
->()
->();
= ->(, );
::(, ->());
}
}
Usage Example
<?php
use App\Infrastructure\Http\MiddlewarePipeline;
use App\Infrastructure\Http\ControllerHandler;
$pipeline = (new MiddlewarePipeline(new NotFoundHandler()))
->pipe(new ErrorHandlingMiddleware($logger))
->pipe(new CorsMiddleware())
->pipe(new LoggingMiddleware($logger))
->pipe(new AuthenticationMiddleware($tokenValidator));
$response = $pipeline->handle($request);
Requirements
{
"require": {
"psr/http-server-handler": "^1.0",
"psr/http-server-middleware": "^1.0"
}
}