Middleware
Middleware augments the functionality of handlers by invoking them in the process of generating responses. Middleware is implemented as a higher order function that takes the following form.
use Psr\Http\Message\RequestInterface;
function my_middleware()
{
return function (callable $handler) {
return function (RequestInterface $request, array $options) use ($handler) {
return $handler($request, $options);
};
};
}
Middleware functions return a function that accepts the next handler to invoke. This returned function then returns another function that acts as a composed handler— it accepts a request and options, and returns a promise that is fulfilled with a response. Your composed middleware can modify the request, add custom request options, and modify the promise returned by the downstream handler.
Here’s an example of adding a header to each request.
use Psr\Http\Message\RequestInterface;
function add_header($header, $value)
{
return function (callable $handler) use ($header, $value) {
return function (
RequestInterface $request,
array $options
) use ($handler, $header, $value) {
$request = $request->withHeader($header, $value);
return $handler($request, $options);
};
};
}
Once a middleware has been created, you can add it to a client by either wrapping the handler used by the client or by decorating a handler stack.
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\Client;
$stack = new HandlerStack();
$stack->setHandler(new CurlHandler());
$stack->push(add_header('X-Foo', 'bar'));
$client = new Client(['handler' => $stack]);
Now when you send a request, the client will use a handler composed with your added middleware, adding a header to each request.
Here’s an example of creating a middleware that modifies the response of the downstream handler. This example adds a header to the response.
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\Client;
function add_response_header($header, $value)
{
return function (callable $handler) use ($header, $value) {
return function (
RequestInterface $request,
array $options
) use ($handler, $header, $value) {
$promise = $handler($request, $options)
return $promise->then(
function (ResponseInterface $response) use ($header, $value) {
return $response->withHeader($header, $value);
}
);
}
};
}
$stack = new HandlerStack();
$stack->setHandler(new CurlHandler());
$stack->push(add_response_header('X-Foo', 'bar'));
$client = new Client(['handler' => $stack]);
Creating a middleware that modifies a request is made much simpler using the GuzzleHttp\Middleware::mapRequest()
middleware. This middleware accepts a function that takes the request argument and returns the request to send.
use Psr\Http\Message\RequestInterface;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\Client;
use GuzzleHttp\Middleware;
$stack = new HandlerStack();
$stack->setHandler(new CurlHandler());
$stack->push(Middleware::mapRequest(function (RequestInterface $request) {
return $request->withHeader('X-Foo', 'bar');
}));
$client = new Client(['handler' => $stack]);
Modifying a response is also much simpler using the GuzzleHttp\Middleware::mapResponse()
middleware.
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\Client;
use GuzzleHttp\Middleware;
$stack = new HandlerStack();
$stack->setHandler(new CurlHandler());
$stack->push(Middleware::mapResponse(function (ResponseInterface $response) {
return $response->withHeader('X-Foo', 'bar');
}));
$client = new Client(['handler' => $stack]);