Gestori e middleware nell'AWS SDK for PHPVersione 3 - AWS SDK for PHP

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Gestori e middleware nell'AWS SDK for PHPVersione 3

Il meccanismo principale per estendere l'AWS SDK for PHP è attraverso gestori e middleware. Ogni classe di client SDK possiede un'istanza Aws\HandlerList accessibile tramite il metodo getHandlerList() di un client. Puoi recuperare un HandlerList del client e modificarlo per aggiungere o rimuovere il comportamento client.

Gestori

Un gestore è una funzione che esegue l'effettiva trasformazione di un comando e richiesta in un risultato. Un gestore in genere invia richieste HTTP. I gestori possono essere composti con middleware per potenziare il comportamento. Un gestore è una funzione che accetta un Aws\CommandInterface e un Psr\Http\Message\RequestInterface e restituisce una promessa che viene soddisfatta con un Aws\ResultInterface o respinta con un motivo Aws\Exception\AwsException.

Ecco un gestore che restituisce lo stesso risultato fittizio per ogni chiamata.

use Aws\CommandInterface; use Aws\Result; use Psr\Http\Message\RequestInterface; use GuzzleHttp\Promise; $myHandler = function (CommandInterface $cmd, RequestInterface $request) { $result = new Result(['foo' => 'bar']); return Promise\promise_for($result); };

Puoi quindi utilizzare questo gestore con un client SDK fornendo un'opzione handler nel costruttore di un client.

// Set the handler of the client in the constructor $s3 = new Aws\S3\S3Client([ 'region' => 'us-east-1', 'version' => '2006-03-01', 'handler' => $myHandler ]);

Puoi anche modificare il gestore di un client dopo che è stata costruito utilizzando il metodo setHandler di un Aws\ClientInterface.

// Set the handler of the client after it is constructed $s3->getHandlerList()->setHandler($myHandler);
Nota

Per cambiare il gestore di un client multiregione dopo averlo creato, usa iluseCustomHandlerMetodo diAws\MultiRegionClient.

$multiRegionClient->useCustomHandler($myHandler);

Gestore fittizio

Ti consigliamo di usare il MockHandler quando scrivi test che utilizzano l'SDK. Puoi usare Aws\MockHandler per restituire risultati fittizi o generare eccezioni fittizie. Tu metti in coda i risultati o le eccezioni e MockHandler li rimuove in ordine FIFO.

use Aws\Result; use Aws\MockHandler; use Aws\DynamoDb\DynamoDbClient; use Aws\CommandInterface; use Psr\Http\Message\RequestInterface; use Aws\Exception\AwsException; $mock = new MockHandler(); // Return a mocked result $mock->append(new Result(['foo' => 'bar'])); // You can provide a function to invoke; here we throw a mock exception $mock->append(function (CommandInterface $cmd, RequestInterface $req) { return new AwsException('Mock exception', $cmd); }); // Create a client with the mock handler $client = new DynamoDbClient([ 'region' => 'us-west-2', 'version' => 'latest', 'handler' => $mock ]); // Result object response will contain ['foo' => 'bar'] $result = $client->listTables(); // This will throw the exception that was enqueued $client->listTables();

Middleware

Il middleware è uno speciale tipo di funzioni di alto livello che migliorano il comportamento di trasferimento di un comando ed eseguono la delega a un gestore "successivo". Le funzioni middleware accettano Aws\CommandInterface e Psr\Http\Message\RequestInterface e restituiscono una promessa che viene soddisfatta con Aws\ResultInterface o respinta con un motivo Aws\Exception\AwsException.

Un middleware è una funzione di ordine più alto che modifica un comando, richiesta o risultato quando passa attraverso il middleware. Un middleware ha la forma seguente.

use Aws\CommandInterface; use Psr\Http\Message\RequestInterface; $middleware = function () { return function (callable $handler) use ($fn) { return function ( CommandInterface $command, RequestInterface $request = null ) use ($handler, $fn) { // Do something before calling the next handler // ... $promise = $fn($command, $request); // Do something in the promise after calling the next handler // ... return $promise; }; }; };

Un middleware riceve un comando per l'esecuzione e un oggetto di richiesta opzionale. Il middleware può scegliere di potenziare la richiesta e il comando o di lasciarli senza alcuna modifica. Un middleware invoca quindi l'handle successivo nella catena o può scegliere di cortocircuitare il gestore successivo e restituire una promessa. La promessa creata invocando il gestore successivo può essere potenziata utilizzando il metodo then della promessa di modificare il risultato o l'errore prima di restituire la promessa dello stack di middleware.

HandlerList

L'SDK usa un Aws\HandlerList per gestire il middleware e i gestori utilizzati quando si esegue un comando. Ogni client SDK possiede un HandlerListe questo HandlerList viene clonato e aggiunto a ogni comando creato da un client. Puoi collegare un middleware e gestore predefinito da utilizzare per ogni comando creato da un client aggiungendo un middleware all'HandlerList del client. Puoi aggiungere e rimuovere middleware da comandi specifici modificando l'HandlerList di proprietà di un comando specifico.

Un HandlerList rappresenta uno stack di middleware che vengono utilizzato per avvolgere un gestore. Per aiutarti a gestire l'elenco di middleware e l'ordine in cui avvolgono un handler, l'HandlerList divide lo stack middleware in passaggi denominati che rappresentano parte del ciclo di vita di trasferimento di un comando:

  1. init - Aggiungi parametri di default

  2. validate - Convalida parametri obbligatori

  3. build - Serializza una richiesta HTTP per l'invio

  4. sign - Firma la richiesta HTTP serializzata

  5. <gestore > (non una fase, ma esegue il trasferimento effettivo)

init

Questa fase del ciclo di vita rappresenta l'inizializzazione di un comando e una richiesta non è stata ancora serializzata. Questa fase viene in genere utilizzata per aggiungere parametri di default a un comando.

Puoi aggiungere un middleware alla fase init usando i metodi appendInit e prependInit, dove appendInit aggiunge il middleware alla fine dell'elenco prepend mentre prependInit aggiunge il middleware all'inizio dell'elenco prepend.

use Aws\Middleware; $middleware = Middleware::tap(function ($cmd, $req) { // Observe the step }); // Append to the end of the step with a custom name $client->getHandlerList()->appendInit($middleware, 'custom-name'); // Prepend to the beginning of the step $client->getHandlerList()->prependInit($middleware, 'custom-name');
validate

Questa fase del ciclo di vita viene utilizzata per convalidare i parametri di input di un comando.

Puoi aggiungere un middleware alla fase validate usando i metodi appendValidate e prependValidate, dove appendValidate aggiunge il middleware alla fine dell'elenco validate mentre prependValidate aggiunge il middleware all'inizio dell'elenco validate.

use Aws\Middleware; $middleware = Middleware::tap(function ($cmd, $req) { // Observe the step }); // Append to the end of the step with a custom name $client->getHandlerList()->appendValidate($middleware, 'custom-name'); // Prepend to the beginning of the step $client->getHandlerList()->prependValidate($middleware, 'custom-name');
build

Questa fase del ciclo di vita viene utilizzata per serializzare una richiesta HTTP per il comando in esecuzione. Gli eventi del ciclo di vita a valle riceveranno un comando e una richiesta PSR-7 HTTP.

Puoi aggiungere un middleware alla fase build usando i metodi appendBuild e prependBuild, dove appendBuild aggiunge il middleware alla fine dell'elenco build mentre prependBuild aggiunge il middleware all'inizio dell'elenco build.

use Aws\Middleware; $middleware = Middleware::tap(function ($cmd, $req) { // Observe the step }); // Append to the end of the step with a custom name $client->getHandlerList()->appendBuild($middleware, 'custom-name'); // Prepend to the beginning of the step $client->getHandlerList()->prependBuild($middleware, 'custom-name');
sign

Questa fase del ciclo di vita viene in genere utilizzata per firmare le richieste HTTP prima che siano inviate tramite la rete. È consigliabile in genere non mutare mai una richiesta HTTP dopo averla firmata per evitare errori di firma.

Questa è l'ultima fase di HandlerList prima che la richiesta HTTP viene trasferita da un gestore.

Puoi aggiungere un middleware alla fase sign usando i metodi appendSign e prependSign, dove appendSign aggiunge il middleware alla fine dell'elenco sign mentre prependSign aggiunge il middleware all'inizio dell'elenco sign.

use Aws\Middleware; $middleware = Middleware::tap(function ($cmd, $req) { // Observe the step }); // Append to the end of the step with a custom name $client->getHandlerList()->appendSign($middleware, 'custom-name'); // Prepend to the beginning of the step $client->getHandlerList()->prependSign($middleware, 'custom-name');

Middleware disponibile

L'SDK fornisce diversi middleware che puoi utilizzare per potenziare il comportamento di un client o per osservare l'esecuzione di un comando.

mapCommand

Il middleware Aws\Middleware::mapCommand è utile quando devi modificare un comando prima che il comando venga serializzato come una richiesta HTTP. Ad esempio, mapCommand può essere utilizzato per eseguire la convalida o aggiungere parametri di default. La funzione mapCommand accetta un chiamabile che accetta un oggetto Aws\CommandInterface e restituisce un oggetto Aws\CommandInterface.

use Aws\Middleware; use Aws\CommandInterface; // Here we've omitted the require Bucket parameter. We'll add it in the // custom middleware. $command = $s3Client->getCommand('HeadObject', ['Key' => 'test']); // Apply a custom middleware named "add-param" to the "init" lifecycle step $command->getHandlerList()->appendInit( Middleware::mapCommand(function (CommandInterface $command) { $command['Bucket'] = 'mybucket'; // Be sure to return the command! return $command; }), 'add-param' );

mapRequest

Il middleware Aws\Middleware::mapRequest è utile quando devi modificare una richiesta dopo che è stata serializzata ma prima che è stata inviata. Ad esempio, questo può essere utilizzato per aggiungere intestazioni HTTP personalizzate a una richiesta. La funzione mapRequest accetta un chiamabile che accetta un argomento Psr\Http\Message\RequestInterface e restituisce un oggetto Psr\Http\Message\RequestInterface.

use Aws\Middleware; use Psr\Http\Message\RequestInterface; // Create a command so that we can access the handler list $command = $s3Client->getCommand('HeadObject', [ 'Key' => 'test', 'Bucket' => 'mybucket' ]); // Apply a custom middleware named "add-header" to the "build" lifecycle step $command->getHandlerList()->appendBuild( Middleware::mapRequest(function (RequestInterface $request) { // Return a new request with the added header return $request->withHeader('X-Foo-Baz', 'Bar'); }), 'add-header' );

Quando si esegue il comando, viene inviata con l'intestazione personalizzata.

Importante

Si noti che il middleware è stato aggiunto all'elenco dei gestori alla fine della fase build. Questo è per far sì che una richiesta sia stata creata prima della chiamata del middleware.

mapResult

Il middleware Aws\Middleware::mapResult è utile quando devi modificare il risultato dell'esecuzione di un comando. La funzione mapResult accetta un chiamabile che accetta un argomento Aws\ResultInterface e restituisce un oggetto Aws\ResultInterface.

use Aws\Middleware; use Aws\ResultInterface; $command = $s3Client->getCommand('HeadObject', [ 'Key' => 'test', 'Bucket' => 'mybucket' ]); $command->getHandlerList()->appendSign( Middleware::mapResult(function (ResultInterface $result) { // Add a custom value to the result $result['foo'] = 'bar'; return $result; }) );

Ora quando il comando viene eseguito, il risultato restituito conterrà un attributo foo.

history

Il middleware history è utile per verificare che l'SDK abbia eseguito i comandi previsti, inviato le richieste HTTP previste e ricevuto i risultati previsti. È essenzialmente un middleware che agisce in modo analogo alla cronologia di un browser Web.

use Aws\History; use Aws\Middleware; $ddb = new Aws\DynamoDb\DynamoDbClient([ 'version' => 'latest', 'region' => 'us-west-2' ]); // Create a history container to store the history data $history = new History(); // Add the history middleware that uses the history container $ddb->getHandlerList()->appendSign(Middleware::history($history));

Un container cronologico Aws\History memorizza 10 voci per impostazione predefinita prima di rimuovere le voci. Puoi personalizzare il numero di voci passando il numero di voci che persistono al costruttore.

// Create a history container that stores 20 entries $history = new History(20);

Puoi controllare il container cronologico dopo l'esecuzione di richieste che passano il middleware di cronologia.

// The object is countable, returning the number of entries in the container count($history); // The object is iterable, yielding each entry in the container foreach ($history as $entry) { // You can access the command that was executed var_dump($entry['command']); // The request that was serialized and sent var_dump($entry['request']); // The result that was received (if successful) var_dump($entry['result']); // The exception that was received (if a failure occurred) var_dump($entry['exception']); } // You can get the last Aws\CommandInterface that was executed. This method // will throw an exception if no commands have been executed. $command = $history->getLastCommand(); // You can get the last request that was serialized. This method will throw an exception // if no requests have been serialized. $request = $history->getLastRequest(); // You can get the last return value (an Aws\ResultInterface or Exception). // The method will throw an exception if no value has been returned for the last // executed operation (e.g., an async request has not completed). $result = $history->getLastReturn(); // You can clear out the entries using clear $history->clear();

tap

Il middleware tap viene utilizzato come osservatore. Puoi usare questo middleware per richiamare le funzioni quando invii comandi attraverso la catena di middleware. La funzione tap accetta un chiamabile che accetta Aws\CommandInterface e un ulteriore Psr\Http\Message\RequestInterface che viene eseguito.

use Aws\Middleware; $s3 = new Aws\S3\S3Client([ 'region' => 'us-east-1', 'version' => '2006-03-01' ]); $handlerList = $s3->getHandlerList(); // Create a tap middleware that observes the command at a specific step $handlerList->appendInit( Middleware::tap(function (CommandInterface $cmd, RequestInterface $req = null) { echo 'About to send: ' . $cmd->getName() . "\n"; if ($req) { echo 'HTTP method: ' . $request->getMethod() . "\n"; } } );

Creazione di gestori personalizzati

Un gestore è semplicemente una funzione che accetta un oggetto Aws\CommandInterface e un oggetto Psr\Http\Message\RequestInterface e restituisce un GuzzleHttp\Promise\PromiseInterface che viene soddisfatto con un Aws\ResultInterface o rifiutato con un Aws\Exception\AwsException.

Sebbene l'SDK disponga di diverse opzioni @http, un gestore deve sapere solo come utilizzare le seguenti opzioni:

A meno che l'opzione non sia specificata come opzionale, un gestore DEVE essere in grado di gestire l'opzione oppure DEVE restituire una promessa rifiutata.

Oltre alla gestione specifica@httpopzioni, un gestore DEVE aggiungere unUser-Agentintestazione che assume il seguente formato, dove «3.X» può essere sostituito conAws\Sdk::VERSIONe»HandlerSpecificData/version...» deve essere sostituito con la stringa User-Agent specifica del gestore.

User-Agent: aws-sdk-php/3.X HandlerSpecificData/version ...