Handlers and Middleware

Os clientes Guzzle utilizam um sistema de manipulador e middleware para enviar pedidos HTTP.

Handlers

Uma função de manuseamento aceita Psr\Http\Message\RequestInterface e matriz de opções de pedido e retorna um GuzzleHttp\Promise\PromiseInterface isto é preenchido com um Psr\Http\Message\ResponseInterface ou rejeitado com um excepção.

Pode fornecer um manipulador personalizado a um cliente usando a opção handler de um construtor cliente. É importante compreender que vários pedidos as opções utilizadas pela Guzzle requerem que o manipulador utilizado seja embrulhado por middlewares específicos pelo cliente. Pode garantir que o manipulador que fornece a um cliente utiliza o middlewares padrão, envolvendo o manipulador no GuzzleHttp\HandlerStack::create(callable $handler = null) método estático.

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;

$handler = new CurlHandler();
$stack = HandlerStack::create($handler); // Wrap w/ middleware
$client = new Client(['handler' => $stack]);

O método create add default handlers to the HandlerStack. Quando o HandlerStack for resolvido, os manipuladores executarão na seguinte ordem:

  1. Pedido de envio:
  1. http_errors - Sem op quando se envia um pedido. O código de estado da resposta é verificado no processamento da resposta ao devolver uma promessa de resposta a pilha.
  2. allow_redirects - Sem op quando se envia um pedido. Seguem-se os redireccionamentos ocorre quando uma promessa de resposta está a ser devolvida para cima da pilha.
  3. cookies - Adiciona cookies aos pedidos.
  4. prepare_body - O corpo de um pedido HTTP será preparado (por exemplo, adicionar cabeçalhos predefinidos como Content-Length, Content-Type, etc.).
  5. <enviar pedido com handler>
  1. Resposta de processamento:
  1. prepare_body - sem op no processamento de resposta.
  2. cookies - extrai os cookies de resposta para o frasco de cookies.
  3. allow_redirects - Segue redireccionamentos.
  4. http_errors - lança excepções quando o código de estado da resposta >= 400.

Quando fornecido sem argumento $handler, GuzzleHttp\HandlerStack::create()

Importante

O manipulador fornecido a um cliente determina como as opções de pedido são aplicadas e utilizado para cada pedido enviado por um cliente. Por exemplo, se não ter um middleware cookie associado a um cliente, e depois definir o cookies opção de pedido não terá qualquer efeito sobre o pedido.

Middleware

O middleware aumenta a funcionalidade dos manipuladores, invocando-os no processo de geração de respostas. O middleware é implementado como uma ordem superior função que toma a seguinte forma.

use Psr\Http\Message\RequestInterface;

function my_middleware()
{
    return function (callable $handler) {
        return function (RequestInterface $request, array $options) use ($handler) {
            return $handler($request, $options);
        };
    };
}

As funções de middleware devolvem uma função que aceita o próximo manipulador a invocar. Esta função devolvida devolve então outra função que actua como um composto aceita um pedido e opções, e devolve uma promessa que é cumprida com uma resposta. O seu middleware composto pode modificar o pedido, adicionar opções de pedido personalizadas, e modificar a promessa devolvida pelo downstream manipulador.

Aqui está um exemplo de adição de um cabeçalho a cada pedido.

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);
        };
    };
}

Uma vez criado um middleware, pode adicioná-lo a um cliente, envolvendo o manipulador utilizado pelo cliente ou decorando uma pilha de manipuladores.

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]);

Agora quando envia um pedido, o cliente utilizará um manipulador composto com o seu middleware adicionado, adicionando um cabeçalho a cada pedido.

Eis um exemplo de criação de um middleware que modifica a resposta do manipulador a jusante. Este exemplo acrescenta um cabeçalho à resposta.

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]);

A criação de um middleware que modifica um pedido é muito mais simples utilizando o GuzzleHttp\Middleware::mapRequest() middleware. Este middleware aceita uma função que aceita o argumento do pedido e devolve o pedido para enviar.

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]);

Modificar uma resposta é também muito mais simples utilizando o middleware 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]);

HandlerStack

Uma pilha de manipulador representa uma pilha de middleware a aplicar a um manipulador de base função. Pode empurrar o middleware para a pilha para adicionar à parte superior da pilha, e desdobrar o middleware na pilha para o adicionar ao fundo da pilha. Quando a pilha é resolvida, o manipulador é empurrado para a pilha. Cada valor é depois saltou da pilha, envolvendo o valor anterior saltou da empilhar.

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\Utils;
use Psr\Http\Message\RequestInterface;

$stack = new HandlerStack();
$stack->setHandler(Utils::chooseHandler());

$stack->push(Middleware::mapRequest(function (RequestInterface $r) {
    echo 'A';
    return $r;
}));

$stack->push(Middleware::mapRequest(function (RequestInterface $r) {
    echo 'B';
    return $r;
}));

$stack->push(Middleware::mapRequest(function (RequestInterface $r) {
    echo 'C';
    return $r;
}));

$client->request('GET', 'http://httpbin.org/');
// echoes 'ABC';

$stack->unshift(Middleware::mapRequest(function (RequestInterface $r) {
    echo '0';
    return $r;
}));

$client = new Client(['handler' => $stack]);
$client->request('GET', 'http://httpbin.org/');
// echoes '0ABC';

Pode dar um nome ao middleware, o que lhe permite adicionar middleware antes outro middleware nomeado, depois de outro middleware nomeado, ou remover middleware pelo nome.

use Psr\Http\Message\RequestInterface;
use GuzzleHttp\Middleware;

// Add a middleware with a name
$stack->push(Middleware::mapRequest(function (RequestInterface $r) {
    return $r->withHeader('X-Foo', 'Bar');
}, 'add_foo'));

// Add a middleware before a named middleware (unshift before).
$stack->before('add_foo', Middleware::mapRequest(function (RequestInterface $r) {
    return $r->withHeader('X-Baz', 'Qux');
}, 'add_baz'));

// Add a middleware after a named middleware (pushed after).
$stack->after('add_baz', Middleware::mapRequest(function (RequestInterface $r) {
    return $r->withHeader('X-Lorem', 'Ipsum');
}));

// Remove a middleware by name
$stack->remove('add_foo');

Creating a Handler

Como foi dito anteriormente, um manipulador é uma função que aceita um Psr\Http\Message\RequestInterface e conjunto de opções de pedido e devoluções a GuzzleHttp\Promise\PromiseInterface que é cumprida com um Psr\Http\Message\ResponseInterface ou rejeitado com uma excepção.

Um manipulador é responsável pela aplicação do seguinte Request Options. Estas opções de pedido são um subconjunto de opções de pedido chamado "opções de transferência".