Understanding Middleware
Definition
Middleware is code that exists between the request and response, and which can take the incoming request, perform actions based on it, and either complete the response or pass delegation on to the next middleware in the queue.
The purpose
Middleware makes it easier for software developers to implement communication and input/output, so they can focus on the specific purpose of their application.
In web services the Input
represents the Request
received, and Output
represents the Response
to be sent.
Using middlewares
Middleware can be used to, but is not limited to, the following purposes:
- A/B Testing
- Debugging
- Caching
- CORS
- Authentication (HTTP Basic Auth, OAuth 2.0, OpenID)
- CSRF Protection
- Rate Limiting
- Referrals
- IP Restriction
Why Middleware
As seen before, the middleware is called somewhere between receiving the request and emmiting the response.
Note: the response object is subject to changes until emitted
Usage
According to http-interop-middleware
, any callable with the parameters $request, $response, $next
in that order is a middleware
Name | Type | Description |
---|---|---|
$request |
\Psr\Http\Message\ServerRequestInterface | The PSR7 request object |
$response |
\Psr\Http\Message\ResponseInterface | The PSR7 response object |
$next |
callable | The next middleware callable |
Middleware returns an \Psr\Http\Message\ResponseInterface
object.
As a closure
<?php
$middlewareFunction = function ($request, $response, $next) {
// ...
};
As an invokable object
<?php
class MyMiddleware
{
public function __construct(MyDependencyInterface $myDependency)
{
$this->myDependency = $myDependency;
}
public function __invoke()
{
//
}
}
An invokable object is an instance of a class with the
__invoke()
magic method declared
Which one to use
The function definition version can be used when working with simple examples / very small projects for a better understanding. Depending on the programming principles you use and what’s more convenient you can also use function definitions instead of invokable classes.
We strongly recommend that you use the invokable class option.
Why Invokable Objects
Where is the catch? Why use Invokable classes if the functions do the same thing. It all narrows to the point where external resources are involved.
What is the difference between a class and a function?
- A class has access to other methods
- a class has access to dependencies
How does it have access to external resources?
Dependencies are injected
trough the class constructor. (as seen in MyMiddleware
class)
For decoupling
dependencies are represented in Interfaces
, therefore custom implementations can be made if needed.
Coupling is the degree of interdependence between software modules. Decoupling or loose coupling means components are independent and are not aware of each other.
The middleware has access to injected
external resources if created using the factory
design pattern.
How is a middleware called
To call one of the above middleware you must either instatiate a new MyMiddleware
object, or store a function definition in a variable.
<?php
// assuming the request, response and next variables already exist
$middleware($request, $response, $next);
Middleware in (simple) theory
The following example will illustrate how the middleware is called.
An array with functions with the same pattern will be built.
Each function will execute an operation.
In this example the next
parameter won’t be used because the calling order will be sequential.
$middleware = [];
// function 1 - displays one message, function 2 - displays another message. etc.
$middleware[] = function($request, $response, $next) {
// do something
// pass the control to next middleware, can also be called before "doing something"
// $response = $next($request, $response);
return $response;
};
Once the $middleware
array is complete with closures and/or invokable objects it can be iterated.
foreach ($middleware as $callable) {
$response = $middleware($request, $response);
}
echo $response->getBody(); // calls $response->getBody()->toArray() for displaying body contents
Note: in this case $next is not needed as we call each $callable sequentially Note: The response must be manually converted to a string
Middleware in practice
Note: Middlewares won’t be called just using a foreach statement. Requests will be jandled by the application, which will call the correct middlewares.
Example dispatcher applications: Zend Stratiglility, Zend Expressive, etc.
Sources:
This page was generated by GitHub Pages.