Gestionnaires et intergiciels dans le kitAWS SDK for PHPVersion 3 - AWS SDK for PHP

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Gestionnaires et intergiciels dans le kitAWS SDK for PHPVersion 3

La principale méthode utilisée pour développer le kit AWS SDK for PHP consiste à utiliser des gestionnaires et des intergiciels. Chaque classe de client de kit SDK possède une instance Aws\HandlerList accessible via la méthode getHandlerList() d'un client. Vous pouvez récupérer la HandlerList d'un client et la modifier afin d'ajouter ou de supprimer un comportement client.

Gestionnaires

Un gestionnaire est une fonction qui transforme une commande et une requête en un résultat. Il envoie généralement des requêtes HTTP. Les gestionnaires peuvent comporter des intergiciels, qui renforcent leur comportement. Un gestionnaire est une fonction qui accepte un Aws\CommandInterface et un Psr\Http\Message\RequestInterface, et renvoie une promesse exécutée avec un Aws\ResultInterface ou rejetée avec une raison Aws\Exception\AwsException.

Voici un gestionnaire qui renvoie le même résultat fictif pour chaque appel.

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

Vous pouvez utiliser ce gestionnaire avec un client de kit SDK en spécifiant une option handler dans le constructeur du 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 ]);

Vous pouvez également modifier le gestionnaire existant d'un client à l'aide de la méthode setHandler de Aws\ClientInterface.

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

Pour modifier le gestionnaire d'un client multi-régions après sa création, utilisez leuseCustomHandlerMéthode d'un kitAws\MultiRegionClient.

$multiRegionClient->useCustomHandler($myHandler);

Mock Handler

Nous vous recommandons d'utiliser MockHandler lorsque vous écrivez des tests qui utilisent le kit SDK. Aws\MockHandler vous permet de renvoyer des résultats fictifs ou de lancer des exceptions de simulation. Dans ce cas vous mettez en file d'attente les résultats ou les exceptions MockHandler les met en file d'attente dans l'ordre 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();

Intergiciel

Un intergiciel est un type spécial de fonction de haut niveau qui augmente le comportement de transfert d'une commande et délègue la tâche à un gestionnaire « suivant ». Les fonctions d'intergiciel acceptent un Aws\CommandInterface et un Psr\Http\Message\RequestInterface, et renvoient une promesse exécutée avec un Aws\ResultInterface ou rejetée avec une raison Aws\Exception\AwsException.

Un intergiciel est une fonction supérieure qui modifie les commandes, les requêtes ou les résultats qu'il traite. Un intergiciel se présente sous la forme suivante.

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 intergiciel reçoit une commande à exécuter et un objet de requête facultatif. Il peut choisir d'augmenter la requête et la commande ou de les laisser en l'état. Un intergiciel appelle le gestionnaire suivant de la chaîne ou choisit de le court-circuiter et de renvoyer une promesse. La promesse ainsi créée en appelant le gestionnaire suivant peut alors être augmentée à l'aide de la méthode then de la promesse afin de modifier le résultat ou l'erreur avant le renvoi de la promesse à la pile d'intergiciels.

HandlerList

Le kit SDK utilise Aws\HandlerList pour gérer les intergiciels et les gestionnaires utilisés lors de l'exécution d'une commande. Chaque client du kit SDK possède une HandlerList. Cette HandlerList est clonée et ajoutée à chaque commande créée par un client. Vous pouvez attacher un intergiciel et un gestionnaire par défaut à utiliser pour chaque commande créée par un client en ajoutant un intergiciel à la HandlerList du client. Vous pouvez ajouter et supprimer des intergiciels de certaines commandes spécifiques en modifiant la HandlerList appartenant à une commande spécifique.

HandlerList représente une pile d’intergiciels utilisés pour encapsuler un gestionnaire. Pour vous aider à gérer la liste d'intergiciels et l'ordre dans lequel ils encapsulent un gestionnaire, HandlerList divise la pile d'intergiciels en plusieurs étapes nommées qui représentent une partie du cycle de vie du transfert d'une commande :

  1. init - Ajout des paramètres par défaut

  2. validate - Validation des paramètres obligatoires

  3. build - Sérialisation d'une requête HTTP pour envoi

  4. sign - Signature de la requête HTTP sérialisée

  5. <handler> (il ne s’agit pas ici d’une étape, mais du transfert lui-même)

init

Cette étape du cycle de vie représente l'initialisation d'une commande. La requête n'a pas encore été sérialisée. Cette étape est généralement utilisée pour ajouter des paramètres par défaut à une commande.

Vous pouvez ajouter un intergiciel à l'étape init à l'aide des méthodes appendInit et prependInit, où appendInit ajoute l'intergiciel à la fin de la liste prepend, et où prependInit ajoute l'intergiciel au début de la liste 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');
valider

Cette étape du cycle de vie permet de valider les paramètres d'entrée d'une commande.

Vous pouvez ajouter un intergiciel à l'étape validate à l'aide des méthodes appendValidate et prependValidate, où appendValidate ajoute l'intergiciel à la fin de la liste validate, et où prependValidate ajoute l'intergiciel au début de la liste 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

Cette étape du cycle de vie permet de sérialiser une requête HTTP pour la commande en cours d'exécution. Les événements du cycle de vie en aval recevront une commande et une requête HTTP PSR-7.

Vous pouvez ajouter un intergiciel à l'étape build à l'aide des méthodes appendBuild et prependBuild, où appendBuild ajoute l'intergiciel à la fin de la liste build, et où prependBuild ajoute l'intergiciel au début de la liste 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

Cette étape du cycle de vie est généralement utilisée pour signer les requêtes HTTP avant leur envoi sur le réseau. De manière générale, nous vous recommandons d'éviter de muter une requête HTTP qui a déjà été signée afin d'éviter les erreurs de signature.

Il s'agit de la dernière étape de HandlerList avant le transfert de la requête HTTP par un gestionnaire.

Vous pouvez ajouter un intergiciel à l'étape sign à l'aide des méthodes appendSign et prependSign, où appendSign ajoute l'intergiciel à la fin de la liste sign, et où prependSign ajoute l'intergiciel au début de la liste 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');

Intergiciel disponible

Le kit SDK comporte plusieurs intergiciels que vous pouvez utiliser pour augmenter le comportement d'un client ou pour observer l'exécution d'une commande.

mapCommand

L'intergiciel Aws\Middleware::mapCommand vous permet de modifier une commande avant qu'elle ne soit sérialisée en tant que requête HTTP. Par exemple, vous pouvez utiliser mapCommand pour effectuer une validation ou pour ajouter des paramètres par défaut. La fonction mapCommand accepte une fonction de type callable, qui accepte un objet Aws\CommandInterface et renvoie un objet 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

L'intergiciel Aws\Middleware::mapRequest vous permet de modifier une requête après sa sérialisation, mais avant son envoi. Vous pouvez par exemple l'utiliser pour ajouter des en-têtes HTTP personnalisés à une requête. La fonction mapRequest accepte une fonction de type callable, qui accepte un argument Psr\Http\Message\RequestInterface et renvoie un objet 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' );

Désormais, lorsque la commande est exécutée, elle est envoyée avec l'en-tête personnalisé.

Important

Notez que l'intergiciel a été ajouté à la liste des gestionnaires à la fin de l'étape build. Cela permet de s'assurer qu'une requête a été créée avant l'appel de cet intergiciel.

mapResult

L'intergiciel Aws\Middleware::mapResult permet de modifier le résultat de l'exécution d'une commande. La fonction mapResult accepte une fonction de type callable, qui accepte un argument Aws\ResultInterface et renvoie un objet 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; }) );

Désormais, lorsque la commande est exécutée, le résultat renvoyé contient un attribut foo.

historique

L'intergiciel history permet de vérifier que le kit SDK a bien exécuté les commandes attendues, qu'il a bien envoyé les requêtes HTTP spécifiées, et qu'il a bien reçu les résultats escomptés. Globalement, il agit de manière similaire à l'historique d'un navigateur 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 conteneur d'historique Aws\History stocke 10 entrées par défaut avant de purger ses entrées. Vous pouvez personnaliser le nombre d'entrées en indiquant combien le constructeur peut en recevoir.

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

Vous pouvez inspecter le conteneur d'historique après l'exécution de requêtes traitées par l'intergiciel d'historique.

// 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

L'intergiciel tap fonctionne comme un observateur. Vous pouvez l'utiliser pour appeler des fonctions lors de l'envoi de commandes via la chaîne d'intergiciels. La fonction tap accepte une fonction de type callable qui accepte Aws\CommandInterface et une option Psr\Http\Message\RequestInterface en cours d'exécution (facultatif).

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

Création de gestionnaires personnalisés

Un gestionnaire est une fonction qui accepte des objets Aws\CommandInterface et Psr\Http\Message\RequestInterface, et renvoie une promesse GuzzleHttp\Promise\PromiseInterface exécutée avec Aws\ResultInterface ou rejetée avec Aws\Exception\AwsException.

Même si le kit SDK possède plusieurs options @http, un gestionnaire n'a besoin de savoir utiliser que les options suivantes :

Un gestionnaire DOIT pouvoir gérer l'option ou DOIT renvoyer une promesse rejetée, sauf si l'option est spécifiée comme étant facultative.

En plus de la manipulation spécifique@httpoptions, un gestionnaire DOIT ajouter unUser-Agenten-tête qui prend la forme suivante, où « 3.X » peut être remplacé parAws\Sdk::VERSIONet »HandlerSpecificData/version... » doit être remplacé par la chaîne User-Agent spécifique à votre gestionnaire.

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