Controladores y middleware en la versión 3 AWS SDK for PHP - AWS SDK for PHP

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Controladores y middleware en la versión 3 AWS SDK for PHP

El mecanismo principal para ampliarlo AWS SDK for PHP es a través de controladores y middleware. Cada clase de SDK cliente posee una Aws\HandlerList instancia a la que se puede acceder mediante el getHandlerList() método de un cliente. Puede recuperar la HandlerList de un cliente y modificarla para añadir o eliminar el comportamiento del cliente.

Controladores

Un controlador es una función que realiza la transformación real de un comando y una solicitud en un resultado. Un controlador normalmente envía HTTP solicitudes. Los controladores pueden incluir middleware para aumentar su comportamiento. Un controlador es una función que acepta una Aws\CommandInterface y una Psr\Http\Message\RequestInterface y devuelve una promesa que se cumple con una Aws\ResultInterface o se rechaza con un motivo Aws\Exception\AwsException.

A continuación se presenta un controlador que devuelve el mismo resultado simulado para cada llamada.

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

A continuación, puede utilizar este controlador con un SDK cliente proporcionando una handler opción en el constructor de un 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 ]);

También puede cambiar el controlador de un cliente después de crearlo utilizando el método setHandler de una Aws\ClientInterface.

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

Para cambiar el controlador de un cliente después de crearlo utilizando el método useCustomHandler de una Aws\MultiRegionClient.

$multiRegionClient->useCustomHandler($myHandler);

Controlador simulado

Recomendamos usar el MockHandler al escribir pruebas que usen elSDK. Puede utilizar el parámetro Aws\MockHandler para devolver los resultados simulados o lanzar excepciones simuladas. Coloca en cola los resultados o las excepciones y los elimina de la MockHandler cola en orden. 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

El middleware es un tipo especial de función de alto nivel que aumenta el comportamiento de la transferencia de un comando y lo delega al "siguiente" controlador. Las funciones de middleware aceptan una Aws\CommandInterface y una Psr\Http\Message\RequestInterface y devuelven una promesa que se cumple con una Aws\ResultInterface o se rechaza con un motivo Aws\Exception\AwsException.

Un middleware es una función de orden superior que modifica un comando, solicitud o resultado al pasar por el middleware. Un middleware tiene el siguiente aspecto.

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 recibe un comando a ejecutar y un objeto Request opcional. El middleware puede elegir aumentar la solicitud y el comando o dejarlas tal y como están. A continuación, un middleware invoca al siguiente controlador de la cadena o puede optar por cortocircuitar el siguiente controlador y devolver una promesa. La promesa que se crea invocando el siguiente controlador también se puede aumentar utilizando el método then de la promesa para modificar el posible resultado o error antes de devolver la promesa a la pila de middleware.

HandlerList

SDKUtiliza una Aws\HandlerList para gestionar el middleware y los controladores que se utilizan al ejecutar un comando. Cada SDK cliente es propietario de unHandlerList, y este HandlerList se clona y agrega a cada comando que crea un cliente. Puede asociar un middleware y el controlador predeterminado que se va a utilizar para cada comando creado por un cliente añadiendo un middleware a la HandlerList del cliente. Puede añadir y eliminar middleware de comandos específicos modificando la HandlerList propiedad de un comando específico.

Una HandlerList representa una pila de middleware que se utiliza para encapsular un controlador. Para ayudar a administrar la lista de middleware y el orden en que encapsulan un controlador, la HandlerList divide la pila en pasos denominados que representan partes del ciclo de vida de la transferencia de un comando:

  1. init: añade parámetros predeterminados

  2. validate: valida los parámetros obligatorios

  3. build- Serializar una HTTP solicitud de envío

  4. sign- Firme la solicitud serializada HTTP

  5. <controlador> (no es un paso pero ejecuta la transferencia real)

init

Este paso del ciclo de vida representa la inicialización de un comando. Aún no se ha serializado ninguna solicitud. Este paso se suele utilizar para añadir los parámetros predeterminados a un comando.

Puede añadir un middleware al paso init con los métodos appendInit y prependInit, donde appendInit añade el middleware al final de la lista prepend mientras que prependInit añade el middleware al principio de la 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

Este paso del ciclo de vida se utiliza para validar los parámetros de entrada de un comando.

Puede añadir un middleware al paso validate con los métodos appendValidate y prependValidate, donde appendValidate añade el middleware al final de la lista validate mientras que prependValidate añade el middleware al principio de la 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

Este paso del ciclo de vida se utiliza para serializar una HTTP solicitud del comando que se está ejecutando. Los eventos posteriores del ciclo de vida recibirán un comando y una solicitud PSR -7HTTP.

Puede añadir un middleware al paso build con los métodos appendBuild y prependBuild, donde appendBuild añade el middleware al final de la lista build mientras que prependBuild añade el middleware al principio de la 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

Este paso del ciclo de vida se suele utilizar para firmar HTTP las solicitudes antes de que se envíen por cable. Por lo general, debes abstenerte de mutar una HTTP solicitud una vez firmada para evitar errores de firma.

Este es el último paso HandlerList antes de que un gestor transfiera la HTTP solicitud.

Puede añadir un middleware al paso sign con los métodos appendSign y prependSign, donde appendSign añade el middleware al final de la lista sign mientras que prependSign añade el middleware al principio de la 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 disponible

SDKProporciona varios programas intermedios que puede utilizar para mejorar el comportamiento de un cliente o para observar la ejecución de un comando.

mapCommand

El Aws\Middleware::mapCommand middleware es útil cuando se necesita modificar un comando antes de que el comando se serialice como una solicitud. HTTP Por ejemplo, mapCommand se puede utilizar para llevar a cabo una validación o para añadir parámetros predeterminados. La función mapCommand acepta una función invocable que admite un objeto Aws\CommandInterface y devuelve un 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

El middleware Aws\Middleware::mapRequest resulta útil cuando hay que modificar una solicitud después de serializarla pero antes de enviarla. Por ejemplo, esto se puede usar para agregar HTTP encabezados personalizados a una solicitud. La función mapRequest acepta una función invocable que admite un argumento Psr\Http\Message\RequestInterface y devuelve un 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' );

Ahora al ejecutar el comando, se envía con el encabezado personalizado.

importante

Tenga en cuenta que el middleware se adjuntó a la lista de controladores al final del paso build. De este modo, se garantiza que se cree una solicitud antes de invocar este middleware.

mapResult

El middleware Aws\Middleware::mapResult resulta útil para modificar el resultado de una ejecución del comando. La función mapResult acepta una función invocable que admite un argumento Aws\ResultInterface y devuelve un 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; }) );

Ahora cuando se ejecute el comando, el resultado incluirá un atributo foo.

historial

El history middleware es útil para comprobar si SDK ejecutó los comandos esperados, envió las HTTP solicitudes que esperaba y obtuvo los resultados esperados. Se trata básicamente de un middleware que actúa de forma similar al historial de un navegador 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 contenedor de historiales Aws\History almacena 10 entradas de forma predeterminada antes de purgar las entradas. Puede personalizar el número de entradas transfiriendo el número de entradas que desea conservar en el constructor.

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

Puede examinar el contenedor de historiales después de ejecutar las solicitudes que transfieren el middleware del historial.

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

El middleware tap se utiliza como observador. Puede utilizar este middleware para invocar a funciones al enviar los comandos a través de la cadena de middleware. La función tap acepta una función invocable que admite la Aws\CommandInterface y una Psr\Http\Message\RequestInterface opcional que se está ejecutando.

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

Crear controladores personalizados

Un controlador es simplemente una función que acepta un objeto Aws\CommandInterface y un objeto Psr\Http\Message\RequestInterface, y que devuelve una GuzzleHttp\Promise\PromiseInterface que se cumple con una Aws\ResultInterface o se rechaza con una Aws\Exception\AwsException.

Aunque SDK tiene varias @http opciones, un controlador solo necesita saber cómo usar las siguientes opciones:

A menos que la opción se especifique como opcional, un controlador MUST podrá gestionar la opción o devolver una promesa rechazada. MUST

Además de gestionar @http opciones específicas, un controlador MUST añade un User-Agent encabezado que adopta el siguiente formato, en el que se puede reemplazar «3.X» por «HandlerSpecificData/version...» Aws\Sdk::VERSION y se debe reemplazar por la cadena de agente de usuario específica del controlador.

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