Back to Blog
Architecture Deep Dive

Understanding Middleware

The Purpose of Middleware

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 Middleware

Middleware can be used for purposes such as, but not limited to:

  • A/B Testing
  • Debugging
  • Caching
  • CORS
  • Authentication (HTTP Basic Auth, OAuth 2.0, OpenID)
  • CSRF Protection
  • Rate Limiting
  • Referrals
  • IP Restriction

Usage

According to PSR-15: HTTP Server Request Handlers, a component that processes an incoming request and generates a response is a middleware. To be compliant with the PSR-15 standard, the middleware must implement Psr\Http\Server\MiddlewareInterface:

class MyMiddleware implements MiddlewareInterface

The middleware class must then implement the process method:

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface;

Example implementation of a middleware which processes the request:

class ExampleMiddleware implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        //process request

        return $handler->handle($request);
    }
}

Example implementation of a middleware which processes the response:

class ExampleMiddleware implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $response = $handler->handle($request);

        //process response

        return $response;
    }
}

An approach that processes both the request and response:

class ExampleMiddleware implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        //process request

        $response = $handler->handle($request);

        //process response

        return $response;
    }
}

How Middleware Is Called

The application pipeline defines the execution flow. The request passes through the middleware in the pipeline, one by one, in the order they are placed in the pipeline. Each middleware processes the request and/or response and either passes control to the next middleware in the chain or terminates the request and returns a response.

  • If control passes through all middleware successfully, execution is eventually passed to the custom code which generates a response of its own. Execution then passes through the middleware in reverse order and returns the response.
  • If execution is terminated before reaching the custom code (e.g. via an exception), the response is generated by the last middleware reached by the execution.

Middleware in Practice

A simple real world example of middleware usage is the enhancement of a request with the user IP for logging purposes or building reports based on geographical data. For this example the pipeline has a single middleware.

The flow begins with a request. Execution passes control to the IP middleware, which enhances the request with the user's IP and other relevant data. Control passes to the custom handler that processes the request and returns a response. The flow continues in reverse order, back to the IP middleware, which can, if needed, change the output before it gets returned to the user that initiated the request.

Frequently Asked Questions

What is middleware? +

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.

What is the purpose of middleware? +

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.

What can middleware be used for? +

Middleware can be used for purposes such as A/B testing, debugging, caching, CORS, authentication (HTTP Basic Auth, OAuth 2.0, OpenID), CSRF protection, rate limiting, referrals, and IP restriction.

What interface must PHP middleware implement to be PSR-15 compliant? +

According to PSR-15, a compliant middleware must implement `Psr\Http\Server\MiddlewareInterface`, which requires a `process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface` method.

How does middleware get called within the application pipeline? +

The application pipeline defines the execution flow: the request passes through the middleware one by one, in the order they are placed. If control passes through all middleware successfully, execution is passed to your custom code, which generates a response, and execution then passes back through the middleware in reverse order. If execution is terminated before reaching your custom code (e.g. via an exception), the response is generated by the last middleware reached.

What is a practical, real-world example of middleware? +

A simple example is enhancing a request with the user's IP for logging purposes or geographical reporting. The request first passes through the IP middleware, which enhances the request with the user's IP and other relevant data, then control passes to the custom handler that processes the request and returns a response. The flow continues in reverse, back through the IP middleware, which can change the output before it's returned to the user.