Manipuladores e middleware na versão 3 AWS SDK for PHP - AWS SDK for PHP

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Manipuladores e middleware na versão 3 AWS SDK for PHP

O principal mecanismo para estender o AWS SDK for PHP é por meio de manipuladores e middleware. Cada classe de SDK cliente possui uma Aws\HandlerList instância que pode ser acessada por meio do getHandlerList() método de um cliente. Você pode recuperar a HandlerList de um cliente e modificá-la para adicionar ou remover o comportamento do cliente.

Manipuladores

Um manipulador é uma função que executa a transformação real de um comando e de uma solicitação em um resultado. Um manipulador normalmente envia HTTP solicitações. Os manipuladores podem ser compostos com middleware para aumentar seu comportamento. Um manipulador é uma função que aceita uma Aws\CommandInterface e uma Psr\Http\Message\RequestInterface e retorna uma promessa que é cumprida com uma Aws\ResultInterface ou rejeitada com uma razão de Aws\Exception\AwsException.

Este é um manipulador que retorna o mesmo resultado simulado para cada chamada.

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

Em seguida, você pode usar esse manipulador com um SDK cliente fornecendo uma handler opção no construtor de um cliente.

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

Você também pode alterar o manipulador de um cliente depois que ele for construído usando o método setHandler de uma Aws\ClientInterface.

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

Para alterar o manipulador de um cliente multirregional após sua construção, use o método useCustomHandler de um Aws\MultiRegionClient.

$multiRegionClient->useCustomHandler($myHandler);

Manipulador simulado

Recomendamos usar o MockHandler ao escrever testes que usam SDK o. Você pode usar o Aws\MockHandler para retornar resultados simulados ou gerar exceções simuladas. Você coloca os resultados ou exceções na fila e, em seguida, os MockHandler desenfileira em ordem. 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

Middleware é um tipo especial de função de alto nível que aumenta o comportamento de transferência de um comando, e delega para um "próximo" manipulador. As funções de middleware aceitam uma Aws\CommandInterface e uma Psr\Http\Message\RequestInterface e retornam uma promessa que é cumprida com uma Aws\ResultInterface ou rejeitada com um motivo de Aws\Exception\AwsException.

Um middleware é uma função de ordem superior que modifica um comando, solicitação ou resultado que é passado por meio do middleware. Um middleware assume a seguinte forma.

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

Um middleware recebe um comando para execução e um objeto de solicitação opcional. O middleware pode optar por aumentar a solicitação e o comando ou deixá-los no estado em que se encontram. Em seguida, um middleware chama a próxima alça na cadeia ou pode escolher dar um curto circuito no próximo manipulador e retornar uma promessa. A promessa criada chamando o próximo manipulador pode ser aumentada usando o método then da promessa para modificar o eventual resultado ou o erro antes de retornar a promessa de volta para a pilha do middleware.

HandlerList

O SDK usa an Aws\HandlerList para gerenciar o middleware e os manipuladores usados ao executar um comando. Cada SDK cliente possui umHandlerList, e isso HandlerList é clonado e adicionado a cada comando que um cliente cria. Você pode anexar um middleware e um manipulador padrão a ser usado para cada comando criado por um cliente adicionando um middleware à HandlerList do cliente. Você pode adicionar e remover o middleware de comandos específicos modificando a HandlerList de propriedade de um comando específico.

Uma HandlerList representa uma pilha de middleware que é usada para encapsular um manipulador. Para ajudar a gerenciar a lista de middleware e a ordem na qual ela encapsula um manipulador, a HandlerList divide a pilha de middleware em etapas nomeadas que representam parte do ciclo de vida da transferência de um comando:

  1. init - adicionar parâmetros padrão

  2. validate - validar parâmetros necessários

  3. build- Serializar uma HTTP solicitação para envio

  4. sign- Assine a solicitação serializada HTTP

  5. <handler> (não é uma etapa, mas executa a transferência real)

init

Essa etapa do ciclo de vida representa a inicialização de um comando, e uma solicitação ainda não foi serializada. Essa etapa geralmente é usada para adicionar parâmetros padrão a um comando.

Você pode adicionar um middleware à etapa init usando os métodos appendInit e prependInit, em que appendInit adiciona o middleware ao final da lista prepend enquanto prependInit adiciona o middleware na frente da lista 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');
validar

Essa etapa do ciclo de vida é usada para validar os parâmetros de entrada de um comando.

Você pode adicionar um middleware à etapa validate usando os métodos appendValidate e prependValidate, em que appendValidate adiciona o middleware ao final da lista validate enquanto prependValidate adiciona o middleware na frente da lista 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

Essa etapa do ciclo de vida é usada para serializar uma HTTP solicitação para o comando que está sendo executado. Os eventos do ciclo de vida downstream receberão um comando e PSR uma solicitação -7. HTTP

Você pode adicionar um middleware à etapa build usando os métodos appendBuild e prependBuild, em que appendBuild adiciona o middleware ao final da lista build enquanto prependBuild adiciona o middleware na frente da lista 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

Essa etapa do ciclo de vida geralmente é usada para assinar HTTP solicitações antes que elas sejam enviadas pela rede. Normalmente, você deve evitar a alteração de uma HTTP solicitação depois que ela é assinada para evitar erros de assinatura.

Essa é a última etapa HandlerList antes de a HTTP solicitação ser transferida por um manipulador.

Você pode adicionar um middleware à etapa sign usando os métodos appendSign e prependSign, em que appendSign adiciona o middleware ao final da lista sign enquanto prependSign adiciona o middleware na frente da lista 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 disponível

O SDK fornece vários middlewares que você pode usar para aumentar o comportamento de um cliente ou observar a execução de um comando.

mapCommand

O Aws\Middleware::mapCommand middleware é útil quando você precisa modificar um comando antes que o comando seja serializado como uma solicitação. HTTP Por exemplo, mapCommand pode ser usado para executar a validação ou adicionar parâmetros padrão. A função mapCommand aceita um chamável que aceita um objeto Aws\CommandInterface e retorna um objeto 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'] = 'amzn-s3-demo-bucket'; // Be sure to return the command! return $command; }), 'add-param' );

mapRequest

O middleware Aws\Middleware::mapRequest é útil quando você precisa modificar uma solicitação depois de ela ser serializada, mas antes de ela ser enviada. Por exemplo, isso pode ser usado para adicionar HTTP cabeçalhos personalizados a uma solicitação. A função mapRequest aceita um chamável que aceita um argumento Psr\Http\Message\RequestInterface e retorna um objeto 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' => 'amzn-s3-demo-bucket' ]); // 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' );

Agora quando o comando for executado, ele será enviado com o cabeçalho personalizado.

Importante

Observe que o middleware foi acrescentado à lista de manipuladores no final da etapa build. Isso é para garantir que uma solicitação tenha sido criada antes desse middleware ser invocado.

mapResult

O middleware Aws\Middleware::mapResult é útil quando você precisa modificar o resultado da execução de um comando. A função mapResult aceita um chamável que aceita um argumento Aws\ResultInterface e retorna um objeto Aws\ResultInterface.

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

Agora quando o comando é executado, o resultado retornado conterá um atributo foo.

história

O history middleware é útil para testar se ele SDK executou os comandos esperados, enviou as HTTP solicitações esperadas e recebeu os resultados esperados. Essencialmente, é um middleware que funciona de forma semelhante ao histórico de um navegador da 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));

Um contêiner de histórico Aws\History armazena 10 entradas por padrão antes de limpar entradas. Você pode personalizar o número de entradas passando o número de entradas a serem persistidas para o construtor.

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

Você pode inspecionar o contêiner do histórico depois de executar solicitações que passam o middleware do histórico.

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

O middleware tap é usado como um observador. Você pode usar esse middleware para invocar funções ao enviar comandos por meio da cadeia de middleware. A função tap aceita um chamável que aceita a Aws\CommandInterface e uma Psr\Http\Message\RequestInterface opcional que está sendo executada.

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

Criação de manipuladores personalizados

Um manipulador é simplesmente uma função que aceita um objeto Aws\CommandInterface e um objeto Psr\Http\Message\RequestInterface e retorna uma GuzzleHttp\Promise\PromiseInterface que é cumprida com uma Aws\ResultInterface ou rejeitada com uma Aws\Exception\AwsException.

Embora o SDK tenha várias @http opções, um manipulador só precisa saber como usar as seguintes opções:

A menos que a opção seja especificada como opcional, um manipulador MUST poderá lidar com a opção ou MUST retornar uma promessa rejeitada.

Além de lidar com @http opções específicas, um manipulador MUST adiciona um User-Agent cabeçalho que assume o seguinte formato, onde “3.X” pode ser substituído por Aws\Sdk::VERSION e “HandlerSpecificData/version...” deve ser substituído pela string User-Agent específica do manipulador.

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