Handlers e Middleware

I client Guzzle usano un sistema di handler e middleware per inviare richieste HTTP.

Gestori

Una funzione gestore accetta un Psr\Http\Message\RequestInterface e un array di e restituisce un GuzzleHttp\Promise\PromiseInterface che viene soddisfatto con un Psr\Http\Message\ResponseInterface o rifiutato con un eccezione.

Si può fornire un gestore personalizzato a un client usando l'opzione handler di un costruttore di client. E' importante capire che diverse opzioni di richiesta utilizzate da Guzzle richiedono che specifici middleware avvolgano l'handler utilizzato dal client. Potete assicurarvi che l'handler che fornite ad un client usi i middlewares predefiniti, avvolgendo l'handler nell'elemento GuzzleHttp\HandlerStack::create(callable $handler = null) metodo statico.

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

Il metodo create aggiunge gestori predefiniti al HandlerStack. Quando il HandlerStack viene risolto, i gestori verranno eseguiti nel seguente ordine:

  1. Invio della richiesta:
  1. http_errors - No op quando si invia una richiesta. Il codice di stato della risposta è controllato nell'elaborazione della risposta quando si restituisce una promessa di risposta lo stack.
  2. allow_redirects - Nessun op quando si invia una richiesta. Seguire i redirect si verifica quando una promessa di risposta viene restituita sullo stack.
  3. cookies - Aggiunge cookie alle richieste.
  4. prepare_body - Il corpo di una richiesta HTTP sarà preparato (es, aggiungere intestazioni predefinite come Content-Length, Content-Type, ecc.)
  5. inviare richiesta con gestore>
  1. Risposta di elaborazione:
  1. prepare_body - nessuna operazione sull'elaborazione della risposta.
  2. cookies - estrae i cookie di risposta nel barattolo dei cookie.
  3. allow_redirects - Segue i redirect.
  4. http_errors - lancia eccezioni quando il codice di stato della risposta = 400.

Quando non viene fornito alcun argomento $handler, GuzzleHttp\HandlerStack::create() sceglierà l'handler più appropriato in base alle estensioni disponibili sul vostro sistema.

Importante

Il gestore fornito ad un client determina come le opzioni di richiesta sono applicate e utilizzate per ogni richiesta inviata da un client. Per esempio, se non si ha si ha un middleware di cookie associato a un client, allora impostando l'opzione cookies opzione di richiesta non avrà alcun effetto sulla richiesta.

Middleware

Il middleware aumenta la funzionalità dei gestori invocandoli nel processo di generazione delle risposte. Il middleware è implementato come una funzione di ordine superiore che assume la seguente 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);
        };
    };
}

Le funzioni middleware restituiscono una funzione che accetta il prossimo gestore da invocare. Questa funzione restituisce poi un'altra funzione che agisce come un gestore composto composto: accetta una richiesta e delle opzioni, e restituisce una promessa che viene soddisfatta con una risposta. Il middleware composto può modificare la richiesta, aggiungere opzioni di richiesta personalizzate e modificare la promessa restituita dal a valle.

Ecco un esempio di aggiunta di un'intestazione ad ogni richiesta.

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

Una volta che un middleware è stato creato, lo si può aggiungere a un client avvolgendo il gestore usato dal client o decorando uno stack di gestori.

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

Ora, quando inviate una richiesta, il client userà un gestore composto con il vostro middleware aggiunto, aggiungendo un'intestazione ad ogni richiesta.

Ecco un esempio di creazione di un middleware che modifica la risposta del gestore a valle. Questo esempio aggiunge un'intestazione alla risposta.

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

Creare un middleware che modifichi una richiesta è reso molto più semplice utilizzando il GuzzleHttp\Middleware::mapRequest() middleware. Questo middleware accetta una funzione che prende l'argomento della richiesta e restituisce la richiesta da inviare.

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

Modificare una risposta è anche molto più semplice usando il 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

Uno stack di gestori rappresenta uno stack di middleware da applicare a una funzione di base del gestore funzione. Si può spingere il middleware sullo stack per aggiungerlo alla cima dello stack, e togliere il middleware dallo stack per aggiungerlo alla fine dello stack. Quando lo stack viene risolto, il gestore viene spinto sullo stack. Ogni valore viene poi tolto dalla pila, avvolgendo il valore precedente tolto dalla pila.

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';

Si può dare un nome al middleware, il che permette di aggiungere middleware prima di altri middleware con nome, dopo altri middleware con nome, o rimuovere middleware per 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');

Creare un Handler

Come detto prima, un gestore è una funzione che accetta un Psr\Http\Message\RequestInterface e un array di opzioni di richiesta e restituisce un GuzzleHttp\Promise\PromiseInterface che viene soddisfatto con un Psr\Http\Message\ResponseInterface o rifiutato con un'eccezione.

Un gestore è responsabile dell'applicazione delle seguenti Opzioni di richiesta. Queste opzioni di richiesta sono un sottoinsieme delle opzioni di richiesta chiamate "opzioni di trasferimento".