Escritura de funciones de Lambda para puntos de acceso de S3 Object Lambda
En esta sección se detalla cómo escribir las funciones de AWS Lambda para usarlas con puntos de acceso de Amazon S3 Object Lambda.
Para obtener información sobre procedimientos integrales completos para algunas tareas de S3 Object Lambda, consulte:
Temas
Trabajar con solicitudes GetObject
en Lambda
En esta sección se asume que el punto de acceso de Object Lambda está configurado para llamar a la función de Lambda para GetObject
. S3 Object Lambda incluye la operación de la API de Amazon S3, WriteGetObjectResponse
, que le permite a la función de Lambda proporcionar datos personalizados y encabezados de respuesta al intermediario de GetObject
.
WriteGetObjectResponse
proporciona un amplio control sobre el código de estado, los encabezados de respuesta y el cuerpo de respuesta, en función de sus necesidades de procesamiento. Puede utilizar WriteGetObjectResponse
para responder con todo el objeto transformado, partes del objeto transformado u otras respuestas en función del contexto de la aplicación. En la siguiente sección se muestran ejemplos únicos del uso de la operación de la API WriteGetObjectResponse
.
-
Ejemplo 1: responder con un código de estado HTTP 403 (Prohibido)
-
Ejemplo 2: responder con una imagen transformada
-
Ejemplo 3: transmitir contenido comprimido
Ejemplo 1: responder con un código de estado HTTP 403 (Prohibido)
Puede usar WriteGetObjectResponse
para responder con el código de estado HTTP 403 (Prohibido) en función del contenido del objeto.
Ejemplo 2: responder con una imagen transformada
Cuando realice una transformación de imagen, es posible que necesite todos los bytes del objeto de origen antes de comenzar a procesarlos. En este caso, la solicitud WriteGetObjectResponse
devolverá el objeto completo a la aplicación solicitante en una llamada.
Ejemplo 3: transmitir contenido comprimido
Cuando se comprimen objetos, los datos comprimidos se producen de forma progresiva. En consecuencia, la solicitud WriteGetObjectResponse
se puede utilizar para devolver los datos comprimidos tan pronto como estén listos. Como se muestra en el siguiente ejemplo, no es necesario conocer la duración de la transformación completada.
nota
Aunque S3 Object Lambda permite hasta 60 segundos para enviar una respuesta completa al intermediario a través de la solicitud WriteGetObjectResponse
, el tiempo disponible podría ser menor. Por ejemplo, el tiempo de espera de la función de Lambda puede ser inferior a 60 segundos. En otros casos, el intermediario puede tener tiempos de espera más estrictos.
Para que el intermediario original reciba una respuesta que no sea el código de estado HTTP 500 (Error interno del servidor), la llamada de WriteGetObjectResponse
debe completarse. Si la función de Lambda realiza la devolución, mediante con una excepción o de otro modo, antes de que se llame a la API WriteGetObjectResponse
, el intermediario original recibirá una respuesta 500 (Error interno del servidor). Las excepciones lanzadas durante el tiempo que se tarda en completar la respuesta dan como resultado respuestas truncadas al intermediario. Si la función de Lambda recibe un código de estado de HTTP 200 (OK) de la llamada a la API WriteGetObjectResponse
, entonces el intermediario original ha enviado la solicitud completa. La respuesta de la función de Lambda, independientemente de si se produce una excepción o no, es ignorada por S3 Object Lambda.
Cuando se llama a la operación de API WriteGetObjectResponse
, Amazon S3 requiere la ruta y el token de solicitud del contexto del evento. Para obtener más información, consulte Formato y uso del contexto del evento.
Los parámetros de la ruta y del token de solicitud son necesarios para conectar la respuesta de WriteGetObjectResult
con el intermediario original. Aunque siempre es conveniente reintentar las respuestas 500 (Error interno del servidor), debido a que el token de solicitud es un token de un solo uso, los intentos posteriores de utilizarlo podrían dar lugar a respuestas de código de estado HTTP 400 (Solicitud incorrecta). Aunque la llamada a WriteGetObjectResponse
con la ruta los tokens de solicitud no necesariamente debe realizarse desde la función de Lambda invocada, sí debe realizarla una identidad de la misma cuenta. La llamada también debe completarse antes de que la función de Lambda finalice la ejecución.
Trabajar con solicitudes HeadObject
en Lambda
En esta sección se asume que el punto de acceso de Object Lambda está configurado para llamar a la función de Lambda para HeadObject
. Lambda recibirá una carga JSON que contiene una clave llamada headObjectContext
. Dentro del contexto, hay una sola propiedad llamada inputS3Url
, que es una URL prefirmada para el punto de acceso de soporte para HeadObject
.
La URL prefirmada incluirá las siguientes propiedades si se especifican:
-
versionId
(en los parámetros de la consulta) -
requestPayer
(en el encabezadox-amz-request-payer
) -
expectedBucketOwner
(en el encabezadox-amz-expected-bucket-owner
)
Otras propiedades no estarán prefirmadas y, por lo tanto, no se incluirán. Las opciones no firmadas que se envían como encabezados se pueden añadir manualmente a la solicitud al llamar a la URL prefirmada que se encuentra en los encabezados userRequest
. No se admiten las opciones de cifrado del lado del servidor para HeadObject
.
Para conocer los parámetros URI de la sintaxis de la solicitud, consulte HeadObject
en la Referencia de la API de Amazon Simple Storage Service
En el siguiente ejemplo, se muestra una carga de entrada JSON de Lambda para HeadObject
.
{ "xAmzRequestId": "
requestId
", "**headObjectContext**": { "**inputS3Url**": "https://my-s3-ap-111122223333
.s3-accesspoint.us-east-1
.amazonaws.com/example?X-Amz-Security-Token=<snip>" }, "configuration": { "accessPointArn": "arn:aws:s3-object-lambda:us-east-1
:111122223333
:accesspoint/example-object-lambda-ap
", "supportingAccessPointArn": "arn:aws:s3:us-east-1
:111122223333
:accesspoint/example-ap
", "payload": "{}" }, "userRequest": { "url": "https://object-lambda-111122223333
.s3-object-lambda.us-east-1
.amazonaws.com/example
", "headers": { "Host": "object-lambda-111122223333
.s3-object-lambda.us-east-1
.amazonaws.com", "Accept-Encoding": "identity", "X-Amz-Content-SHA256": "e3b0c44298fc1example
" } }, "userIdentity": { "type": "AssumedRole", "principalId": "principalId
", "arn": "arn:aws:sts::111122223333
:assumed-role/Admin/example
", "accountId": "111122223333
", "accessKeyId": "accessKeyId
", "sessionContext": { "attributes": { "mfaAuthenticated": "false", "creationDate": "Wed Mar 10 23:41:52 UTC 2021" }, "sessionIssuer": { "type": "Role", "principalId": "principalId
", "arn": "arn:aws:iam::111122223333
:role/Admin", "accountId": "111122223333
", "userName": "Admin" } } }, "protocolVersion": "1.00" }
La función de Lambda debe devolver un objeto JSON que contenga los encabezados y los valores que se devolverán para la llamada HeadObject
.
En el siguiente ejemplo se muestra la estructura del JSON de la respuesta de Lambda para HeadObject
.
{ "statusCode": <number>; // Required "errorCode": <string>; "errorMessage": <string>; "headers": { "Accept-Ranges": <string>, "x-amz-archive-status": <string>, "x-amz-server-side-encryption-bucket-key-enabled": <boolean>, "Cache-Control": <string>, "Content-Disposition": <string>, "Content-Encoding": <string>, "Content-Language": <string>, "Content-Length": <number>, // Required "Content-Type": <string>, "x-amz-delete-marker": <boolean>, "ETag": <string>, "Expires": <string>, "x-amz-expiration": <string>, "Last-Modified": <string>, "x-amz-missing-meta": <number>, "x-amz-object-lock-mode": <string>, "x-amz-object-lock-legal-hold": <string>, "x-amz-object-lock-retain-until-date": <string>, "x-amz-mp-parts-count": <number>, "x-amz-replication-status": <string>, "x-amz-request-charged": <string>, "x-amz-restore": <string>, "x-amz-server-side-encryption": <string>, "x-amz-server-side-encryption-customer-algorithm": <string>, "x-amz-server-side-encryption-aws-kms-key-id": <string>, "x-amz-server-side-encryption-customer-key-MD5": <string>, "x-amz-storage-class": <string>, "x-amz-tagging-count": <number>, "x-amz-version-id": <string>, <x-amz-meta-headers>: <string>, // user-defined metadata "x-amz-meta-meta1": <string>, // example of the user-defined metadata header, it will need the x-amz-meta prefix "x-amz-meta-meta2": <string> ... }; }
El siguiente ejemplo muestra cómo utilizar la URL prefirmada para rellenar la respuesta modificando los valores del encabezado según sea necesario antes de devolver el JSON.
Trabajar con solicitudes ListObjects
en Lambda
En esta sección se asume que el punto de acceso de Object Lambda está configurado para llamar a la función de Lambda para ListObjects
. Lambda recibirá la carga JSON con un nuevo objeto llamado listObjectsContext
. listObjectsContext
contiene una sola propiedad, inputS3Url
, que es una URL prefirmada para el punto de acceso de soporte para ListObjects
.
A diferencia de GetObject
y HeadObject
, la URL prefirmada incluirá las siguientes propiedades si se especifican:
-
Todos los parámetros de la consulta
-
requestPayer
(en el encabezadox-amz-request-payer
) -
expectedBucketOwner
(en el encabezadox-amz-expected-bucket-owner
)
Para conocer los parámetros URI de la sintaxis de la solicitud, consulte ListObjects
en la Referencia de la API de Amazon Simple Storage Service
importante
Recomendamos que utilice la versión más reciente, ListObjectSv2, cuando desarrolle aplicaciones. Para la compatibilidad con versiones anteriores, Amazon S3 sigue siendo compatible con ListObjects
.
En el siguiente ejemplo, se muestra la carga de entrada JSON de Lambda para ListObjects
.
{ "xAmzRequestId": "
requestId
", "**listObjectsContext**": { "**inputS3Url**": "https://my-s3-ap-111122223333
.s3-accesspoint.us-east-1
.amazonaws.com/?X-Amz-Security-Token=<snip>", }, "configuration": { "accessPointArn": "arn:aws:s3-object-lambda:us-east-1
:111122223333
:accesspoint/example-object-lambda-ap
", "supportingAccessPointArn": "arn:aws:s3:us-east-1
:111122223333
:accesspoint/example-ap
", "payload": "{}" }, "userRequest": { "url": "https://object-lambda-111122223333
.s3-object-lambda.us-east-1
.amazonaws.com/example
", "headers": { "Host": "object-lambda-111122223333
.s3-object-lambda.us-east-1
.amazonaws.com", "Accept-Encoding": "identity", "X-Amz-Content-SHA256": "e3b0c44298fc1example
" } }, "userIdentity": { "type": "AssumedRole", "principalId": "principalId
", "arn": "arn:aws:sts::111122223333
:assumed-role/Admin/example
", "accountId": "111122223333
", "accessKeyId": "accessKeyId
", "sessionContext": { "attributes": { "mfaAuthenticated": "false", "creationDate": "Wed Mar 10 23:41:52 UTC 2021" }, "sessionIssuer": { "type": "Role", "principalId": "principalId
", "arn": "arn:aws:iam::111122223333
:role/Admin", "accountId": "111122223333
", "userName": "Admin" } } }, "protocolVersion": "1.00" }
La función de Lambda debe devolver un objeto JSON que contenga el código de estado, el resultado XML de la lista o la información de error que devolverá el objeto S3 Lambda.
S3 Object Lambda no procesa ni valida listResultXml
, pero en su lugar lo reenvía al intermediario de ListObjects
. Para listBucketResult
, S3 Object Lambda espera que determinadas propiedades sean de un tipo específico y generará excepciones si no puede analizarlas. No se pueden proporcionar listResultXml
y listBucketResult
al mismo tiempo.
En el siguiente ejemplo se muestra cómo usar la URL prefirmada para llamar a Amazon S3 y usar el resultado para rellenar una respuesta, incluida la comprobación de errores.
En el siguiente ejemplo se muestra la estructura del JSON de la respuesta de Lambda para ListObjects
.
{ "statusCode": <number>; // Required "errorCode": <string>; "errorMessage": <string>; "listResultXml": <string>; // This can also be Error XML string in case S3 returned error response when calling the pre-signed URL "listBucketResult": { // listBucketResult can be provided instead of listResultXml, however they can not both be provided in the JSON response "name": <string>, // Required for 'listBucketResult' "prefix": <string>, "marker": <string>, "nextMarker": <string>, "maxKeys": <int>, // Required for 'listBucketResult' "delimiter": <string>, "encodingType": <string> "isTruncated": <boolean>, // Required for 'listBucketResult' "contents": [ { "key": <string>, // Required for 'content' "lastModified": <string>, "eTag": <string>, "checksumAlgorithm": <string>, // CRC32, CRC32C, SHA1, SHA256 "size": <int>, // Required for 'content' "owner": { "displayName": <string>, // Required for 'owner' "id": <string>, // Required for 'owner' }, "storageClass": <string> }, ... ], "commonPrefixes": [ { "prefix": <string> // Required for 'commonPrefix' }, ... ], } }
Trabajar con solicitudes ListObjectsV2
en Lambda
En esta sección se asume que el punto de acceso de Object Lambda está configurado para llamar a la función de Lambda para ListObjectsV2
. Lambda recibirá la carga JSON con un nuevo objeto llamado listObjectsV2Context
. listObjectsV2Context
contiene una sola propiedad, inputS3Url
, que es una URL prefirmada para el punto de acceso de soporte para ListObjectsV2
.
A diferencia de GetObject
y HeadObject
, la URL prefirmada incluirá las siguientes propiedades si se especifican:
-
Todos los parámetros de la consulta
-
requestPayer
(en el encabezadox-amz-request-payer
) -
expectedBucketOwner
(en el encabezadox-amz-expected-bucket-owner
)
Para conocer los parámetros URI de la sintaxis de la solicitud, consulte ListObjectsV2
en la Referencia de la API de Amazon Simple Storage Service
En el siguiente ejemplo, se muestra la carga de entrada JSON de Lambda para ListObjectsV2
.
{ "xAmzRequestId": "
requestId
", "**listObjectsV2Context**": { "**inputS3Url**": "https://my-s3-ap-111122223333
.s3-accesspoint.us-east-1
.amazonaws.com/?list-type=2&X-Amz-Security-Token=<snip>", }, "configuration": { "accessPointArn": "arn:aws:s3-object-lambda:us-east-1
:111122223333
:accesspoint/example-object-lambda-ap
", "supportingAccessPointArn": "arn:aws:s3:us-east-1
:111122223333
:accesspoint/example-ap
", "payload": "{}" }, "userRequest": { "url": "https://object-lambda-111122223333
.s3-object-lambda.us-east-1
.amazonaws.com/example
", "headers": { "Host": "object-lambda-111122223333
.s3-object-lambda.us-east-1
.amazonaws.com", "Accept-Encoding": "identity", "X-Amz-Content-SHA256": "e3b0c44298fc1example
" } }, "userIdentity": { "type": "AssumedRole", "principalId": "principalId
", "arn": "arn:aws:sts::111122223333
:assumed-role/Admin/example
", "accountId": "111122223333
", "accessKeyId": "accessKeyId
", "sessionContext": { "attributes": { "mfaAuthenticated": "false", "creationDate": "Wed Mar 10 23:41:52 UTC 2021" }, "sessionIssuer": { "type": "Role", "principalId": "principalId
", "arn": "arn:aws:iam::111122223333
:role/Admin", "accountId": "111122223333
", "userName": "Admin" } } }, "protocolVersion": "1.00" }
La función de Lambda debe devolver un objeto JSON que contenga el código de estado, el resultado XML de la lista o la información de error que devolverá el objeto S3 Lambda.
S3 Object Lambda no procesa ni valida listResultXml
, pero en su lugar lo reenvía al intermediario de ListObjectsV2
. Para listBucketResult
, S3 Object Lambda espera que determinadas propiedades sean de un tipo específico y generará excepciones si no puede analizarlas. No se pueden proporcionar listResultXml
y listBucketResult
al mismo tiempo.
En el siguiente ejemplo se muestra cómo usar la URL prefirmada para llamar a Amazon S3 y usar el resultado para rellenar una respuesta, incluida la comprobación de errores.
En el siguiente ejemplo se muestra la estructura del JSON de la respuesta de Lambda para ListObjectsV2
.
{ "statusCode": <number>; // Required "errorCode": <string>; "errorMessage": <string>; "listResultXml": <string>; // This can also be Error XML string in case S3 returned error response when calling the pre-signed URL "listBucketResult": { // listBucketResult can be provided instead of listResultXml, however they can not both be provided in the JSON response "name": <string>, // Required for 'listBucketResult' "prefix": <string>, "startAfter": <string>, "continuationToken": <string>, "nextContinuationToken": <string>, "keyCount": <int>, // Required for 'listBucketResult' "maxKeys": <int>, // Required for 'listBucketResult' "delimiter": <string>, "encodingType": <string> "isTruncated": <boolean>, // Required for 'listBucketResult' "contents": [ { "key": <string>, // Required for 'content' "lastModified": <string>, "eTag": <string>, "checksumAlgorithm": <string>, // CRC32, CRC32C, SHA1, SHA256 "size": <int>, // Required for 'content' "owner": { "displayName": <string>, // Required for 'owner' "id": <string>, // Required for 'owner' }, "storageClass": <string> }, ... ], "commonPrefixes": [ { "prefix": <string> // Required for 'commonPrefix' }, ... ], } }