Handlers and Middleware

Guzzle clients gebruiken een handler en middleware systeem om HTTP verzoeken te versturen.

Handlers

Een handler functie accepteert een PsrHttp\MessageRequestInterface en array van verzoekopties en retourneert een GuzzleHttpBelofteBelofteInterface die vervuld met een PsrHttpMessageResponseInterface of afgewezen met een uitzondering.

Je kan een aangepaste handler aan een client geven door gebruik te maken van de handler optie van een client constructor. Het is belangrijk om te begrijpen dat verschillende verzoek opties gebruikt door Guzzle vereisen dat specifieke middlewares de handler gebruiken door de cliënt. Je kunt ervoor zorgen dat de handler die je aan een cliënt geeft de standaard middlewares gebruikt door de handler te verpakken in de GuzzleHttpHandlerStack::create(calllable $handler = null) statische methode.

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

De create methode voegt standaard handlers toe aan de HandlerStack. Wanneer de HandlerStack wordt opgelost, zullen de handlers in de volgende volgorde worden uitgevoerd:

  1. Verzoek verzenden:
  1. http_errors - Geen op bij het versturen van een aanvraag. De statuscode van het antwoord wordt gecontroleerd in de antwoordverwerking bij het terugsturen van een antwoordbelofte de stack.
  2. allow_redirects - Geen op bij het versturen van een verzoek. Het volgen van redirects gebeurt wanneer een antwoordbelofte wordt teruggestuurd naar de stack.
  3. cookies - Voegt cookies toe aan requests.
  4. prepare_body - De body van een HTTP verzoek zal voorbereid worden (bv, standaard headers toevoegen zoals Content-Length, Content-Type, etc.).
  5. <stuur verzoek met handler>
  1. Verwerkings antwoord:
  1. prepare_body - geen op op antwoordverwerking.
  2. cookies - haalt antwoordcookies in de koekjestrommel.
  3. allow_redirects - Volgt redirects.
  4. http_errors - gooit uitzonderingen wanneer de response status code >= 400.

Wanneer er geen $handler argument wordt gegeven, zal GuzzleHttpHandlerStack::create() zal de meest geschikte handler kiezen gebaseerd op de extensies die beschikbaar zijn op je systeem.

Belangrijk

De handler die aan een cliënt wordt verstrekt bepaalt hoe verzoekopties worden toegepast en worden gebruikt voor elk verzoek dat door een cliënt wordt verzonden. Bijvoorbeeld, als je geen een cookie middleware hebt gekoppeld aan een client, dan zal het instellen van de cookies verzoekoptie geen effect hebben op het verzoek.

Middleware

Middleware vergroot de functionaliteit van handlers door ze aan te roepen in het proces van het genereren van antwoorden. Middleware wordt geïmplementeerd als een hogere orde functie die de volgende vorm heeft.

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-functies retourneren een functie die de volgende handler aanvaardt om aan te roepen. Deze geretourneerde functie retourneert dan een andere functie die fungeert als een samengestelde handler-- het accepteert een verzoek en opties, en retourneert een belofte die wordt vervuld met een antwoord. Je samengestelde middleware kan het verzoek wijzigen, aangepaste verzoekopties toevoegen, en de belofte wijzigen die door de downstream afhandelaar.

Hier is een voorbeeld van het toevoegen van een header aan elk verzoek.

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

Zodra een middleware gemaakt is, kan je die toevoegen aan een client door ofwel de handler die door de client gebruikt wordt te wrappen, ofwel door een handler stack te versieren.

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

Wanneer je nu een verzoek verstuurt, zal de client een handler gebruiken die samengesteld is met je toegevoegde middleware, die een header toevoegt aan elk verzoek.

Hier is een voorbeeld van het maken van een middleware die het antwoord van de downstream handler wijzigt. Dit voorbeeld voegt een header toe aan het antwoord.

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

Het maken van een middleware die een verzoek wijzigt is veel eenvoudiger met behulp van de GuzzleHttpMiddleware::mapRequest() middleware. Deze middleware aanvaardt een functie die het request argument neemt en het te verzenden request teruggeeft.

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

Een antwoord wijzigen is ook veel eenvoudiger met de GuzzleHttpMiddleware::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

Een handler stack vertegenwoordigt een stack van middleware om toe te passen op een basis handler functie. Je kunt middleware naar de stack schuiven om toe te voegen aan de top van de stack, en middleware loslaten op de stack om toe te voegen aan de onderkant van de stack. Wanneer de stack wordt opgelost, wordt de handler op de stack geduwd. Elke waarde wordt vervolgens van de stack afgehaald, waarbij de vorige waarde die van de stack.

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

U kunt middleware een naam geven, waardoor u middleware kunt toevoegen vóór andere middleware met een naam, na andere middleware met een naam, of middleware verwijderen op naam.

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

Een Handler maken

Zoals eerder gezegd, is een handler een functie die een PsrHttpMessageRequestInterface en array van verzoekopties en retourneert een GuzzleHttpMessagePromiseInterface die wordt vervuld met een PsrHttpMessageResponseInterface of wordt afgewezen met een exception.

Een handler is verantwoordelijk voor het toepassen van de volgende Verzoekopties. Deze verzoek opties zijn een subset van verzoek opties genaamd "overdrachtsopties".