From beb9fabd4bebd5adcaa855046e7504ce7f18c6f4 Mon Sep 17 00:00:00 2001 From: Daniel Opitz Date: Sat, 6 Jul 2024 13:43:41 +0200 Subject: [PATCH 1/2] Add PSR-15 example --- docs/v4/concepts/middleware.md | 129 ++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 58 deletions(-) diff --git a/docs/v4/concepts/middleware.md b/docs/v4/concepts/middleware.md index e949aa27..e5a95d60 100644 --- a/docs/v4/concepts/middleware.md +++ b/docs/v4/concepts/middleware.md @@ -11,14 +11,18 @@ Middleware is perfect for these scenarios. ## What is middleware? -A middleware implements the [PSR-15 Middleware Interface](https://www.php-fig.org/psr/psr-15/): +Middleware is a layer that sits between the client +request and the server response in a web application. +It intercepts, processes, and potentially alters HTTP requests +and responses as they pass through the application pipeline. -1. `Psr\Http\Message\ServerRequestInterface` - The PSR-7 request object -2. `Psr\Http\Server\RequestHandlerInterface` - The PSR-15 request handler object +Middleware components can handle a variety of tasks such as authentication, +authorization, logging, request modification, response transformation, +error handling, and more. -It can do whatever is appropriate with these objects. -The only hard requirement is that a middleware **MUST** return an instance of `Psr\Http\Message\ResponseInterface`. -Each middleware **SHOULD** invoke the next middleware and pass it the Request object as argument. +Each middleware performs its function and then passes control +to the next component in the chain, enabling a modular and reusable +approach to handling cross-cutting concerns in web applications. ## How does middleware work? @@ -44,12 +48,13 @@ Here's a diagram that illustrates the middleware process flow: Middleware is a callable that accepts two arguments: a `Request` object and a `RequestHandler` object. Each middleware **MUST** return an instance of `Psr\Http\Message\ResponseInterface`. -### Closure middleware example. +### Closure middleware This example middleware is a Closure. ```php add($afterMiddleware); $app->run(); ``` -### Invokable class middleware example +### Invokable class middleware This example middleware is an invokable class that implements the magic `__invoke()` method. ```php add(new ExampleMiddleware()); +To create a PSR-15 middleware class, you need to implement the `MiddlewareInterface`. -// Add Middleware On Route -$app->get('/', function () { ... })->add(new ExampleMiddleware()); +Below is an example of a simple PSR-15 middleware: -// Add Middleware On Group -$app->group('/', function () { ... })->add(new ExampleMiddleware()); +```php +run(); -``` +use Psr\Http\Message\ResponseInterface as Response; +use Psr\Http\Message\ServerRequestInterface as Request; +use Psr\Http\Server\MiddlewareInterface; +use Psr\Http\Server\RequestHandlerInterface as RequestHandler; -## How do I add middleware? +class ExampleMiddleware implements MiddlewareInterface +{ + public function process(Request $request, RequestHandler $handler): Response + { + // Handle the incoming request + // ... -You may add middleware to a Slim application, to an individual Slim application route or to a route group. -All scenarios accept the same middleware and implement the same middleware interface. + // Invoke the next middleware and get response + $response = $handler->handle($request); -### Application middleware + // Handle the outgoing response + // ... -Application middleware is invoked for every **incoming** HTTP request. -Add application middleware with the Slim application instance's **add()** method. -This example adds the Closure middleware example above: + return $response; + } +} -```php -add(function (Request $request, RequestHandler $handler) use ($app) { - $response = $handler->handle($request); - $existingContent = (string) $response->getBody(); +To use a middleware, you need to register each middleware on the Slim **$app**, a route or a route group. - $response = $app->getResponseFactory()->createResponse(); - $response->getBody()->write('BEFORE ' . $existingContent); +```php +// Add middleware to the App +$app->add(new ExampleMiddleware()); - return $response; -}); +// Add middleware to the App using dependency injection +$app->add(ExampleMiddleware::class); -$app->add(function (Request $request, RequestHandler $handler) { - $response = $handler->handle($request); - $response->getBody()->write(' AFTER'); - return $response; -}); +// Add middleware to a route +$app->get('/', function () { ... })->add(new ExampleMiddleware()); -$app->get('/', function (Request $request, Response $response, $args) { - $response->getBody()->write('Hello World'); - return $response; -}); +// Add middleware to a route group +$app->group('/', function () { ... })->add(new ExampleMiddleware()); -$app->run(); ``` -This would output this HTTP response body: +### Middleware execution order -```bash -BEFORE Hello World AFTER +Slim processes middleware in a Last In, First Out (LIFO) order. +This means the last middleware added is the first one to be executed. +If you add multiple middleware components, +they will be executed in the reverse order of their addition. + +```php +$app->add(new MiddlewareOne()); +$app->add(new MiddlewareTwo()); +$app->add(new MiddlewareThree()); ``` +In this case, `MiddlewareThree` will be executed first, +followed by `MiddlewareTwo`, and finally `MiddlewareOne`. + ### Route middleware Route middleware is invoked _only if_ its route matches the current HTTP request method and URI. From 157b565ab68c86c1521954e95ad200541f3e8db8 Mon Sep 17 00:00:00 2001 From: Daniel Opitz Date: Sun, 7 Jul 2024 12:12:57 +0200 Subject: [PATCH 2/2] Add PSR-15 example --- docs/v4/concepts/middleware.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/v4/concepts/middleware.md b/docs/v4/concepts/middleware.md index e5a95d60..4345f912 100644 --- a/docs/v4/concepts/middleware.md +++ b/docs/v4/concepts/middleware.md @@ -16,12 +16,12 @@ request and the server response in a web application. It intercepts, processes, and potentially alters HTTP requests and responses as they pass through the application pipeline. -Middleware components can handle a variety of tasks such as authentication, +A middleware can handle a variety of tasks such as authentication, authorization, logging, request modification, response transformation, error handling, and more. Each middleware performs its function and then passes control -to the next component in the chain, enabling a modular and reusable +to the next middleware in the chain, enabling a modular and reusable approach to handling cross-cutting concerns in web applications. ## How does middleware work?