Écriture de fonctions Lambda pour les points d’accès S3 Object Lambda
Cette section décrit en détail comment écrire des fonctions AWS Lambda à utiliser avec les points d’accès Amazon S3 Object Lambda.
Pour connaître les procédures complètes de bout en bout pour certaines tâches S3 Object Lambda, consultez ce qui suit :
Rubriques
Utilisation de requêtes GetObject
dans Lambda
Cette section suppose que votre point d’accès Object Lambda est configuré pour appeler la fonction Lambda pour GetObject
. S3 Object Lambda inclut l’opération d’API Amazon S3, WriteGetObjectResponse
, qui permet à la fonction Lambda de fournir des données personnalisées et des en-têtes de réponse à l’appelant GetObject
.
WriteGetObjectResponse
vous offre un contrôle étendu sur le code de statut, les en-têtes de réponse et le corps de réponse, en fonction de vos besoins de traitement. Vous pouvez utiliser WriteGetObjectResponse
pour répondre avec l’ensemble de l’objet transformé, des parties de l’objet transformé ou d’autres réponses basées sur le contexte de votre application. La section suivante présente des exemples uniques d’utilisation de l’opération d’API WriteGetObjectResponse
.
-
Exemple 1 : répondre avec un code de statut HTTP 403 (Interdit)
-
Exemple 2 : répondre avec une image transformée
-
Exemple 3 : diffuser du contenu compressé
Exemple 1 : répondre avec un code de statut HTTP 403 (Interdit)
Vous pouvez utiliser WriteGetObjectResponse
pour répondre avec le code d’état HTTP 403 (Interdit) en fonction du contenu de l’objet.
Exemple 2 : répondre avec une image transformée
Lorsque vous effectuez une transformation d’image, vous pouvez constater que vous avez besoin de tous les octets de l’objet source avant de pouvoir commencer à les traiter. Dans ce cas, votre demande WriteGetObjectResponse
renvoie l’objet entier à l’application requérante en un seul appel.
Exemple 3 : diffuser du contenu compressé
Lorsque vous compressez des objets, les données compressées sont produites de manière incrémentielle. Par conséquent, vous pouvez utiliser votre demande WriteGetObjectResponse
pour renvoyer les données compressées dès qu’elles sont prêtes. Comme le montre cet exemple, vous n’avez pas besoin de connaître la longueur de la transformation terminée.
Note
Bien que S3 Object Lambda laisse jusqu’à 60 secondes pour envoyer une réponse complète à l’appelant via la demande WriteGetObjectResponse
, le temps réel disponible peut être inférieur. Par exemple, le délai d’expiration de votre fonction Lambda peut être inférieur à 60 secondes. Dans d’autres cas, l’appelant peut avoir des délais d’attente plus stricts.
Pour que l’appelant d’origine reçoive une réponse autre que le code de statut HTTP 500 (Erreur de serveur interne), l’appel WriteGetObjectResponse
doit être terminé. Si la fonction Lambda renvoie une réponse, avec une exception ou autrement, avant que l’opération d’API WriteGetObjectResponse
soit appelée, l’appelant d’origine reçoit une réponse 500 (Erreur de serveur interne). Les exceptions lancées pendant le temps nécessaire pour compléter la réponse entraînent des réponses tronquées à l’appelant. Si la fonction Lambda reçoit une réponse avec code de statut HTTP 200 (OK) de l’appel d’API WriteGetObjectResponse
, l’appelant d’origine a envoyé la demande complète. La réponse de la fonction Lambda, qu’une exception soit déclenchée ou non, est ignorée par S3 Object Lambda.
Au moment d’appeler l’opération d’API WriteGetObjectResponse
, Amazon S3 exige la route et le jeton de demande du contexte d’événement. Pour plus d’informations, consultez Format et utilisation du contexte d’événement.
Les paramètres de route et de jeton de demande sont nécessaires pour connecter la réponse WriteGetObjectResult
à l’appelant d’origine. Bien qu’il soit toujours approprié de réessayer les réponses 500 (Erreur de serveur interne), car le jeton de demande est un jeton à usage unique, les tentatives ultérieures de l’utiliser peuvent entraîner des réponses avec code de statut HTTP 400 (Demande incorrecte). Bien que l’appel à WriteGetObjectResponse
avec la route et les jetons de demande n’ait pas besoin d’être réalisé à partir de la fonction Lambda invoquée, il doit être réalisé par une identité figurant dans le même compte. L’appel doit également être terminé avant que la fonction Lambda ne termine l’exécution.
Utilisation de requêtes HeadObject
dans Lambda
Cette section suppose que votre point d’accès Object Lambda est configuré pour appeler la fonction Lambda pour HeadObject
. Lambda recevra une charge utile JSON contenant une clé appelée headObjectContext
. Dans le contexte, il existe une propriété unique appelée inputS3Url
, qui est une URL pré-signée pour le point d’accès de prise en charge pour HeadObject
.
L’URL pré-signée inclura les propriétés suivantes si elles sont spécifiées :
-
versionId
(dans les paramètres de la requête) -
requestPayer
(dans l’en-têtex-amz-request-payer
) -
expectedBucketOwner
(dans l’en-têtex-amz-expected-bucket-owner
)
Les autres propriétés ne seront pas pré-signées et ne seront donc pas incluses. Les options non signées envoyées sous forme d’en-têtes peuvent être ajoutées manuellement à la demande lors de l’appel de l’URL pré-signée qui se trouve dans les en-têtes userRequest
. Les options de chiffrement côté serveur ne sont pas prises en charge pour HeadObject
.
Pour les paramètres d’URI de la syntaxe de la demande, consultez HeadObject
dans la Référence des API Amazon Simple Storage Service.
L’exemple suivant illustre une charge utile d’entrée JSON de Lambda pour 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" }
Votre fonction Lambda doit renvoyer un objet JSON contenant les en-têtes et les valeurs qui seront renvoyés pour l’appel HeadObject
.
L’exemple suivant illustre la structure du code JSON de réponse de Lambda pour 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> ... }; }
L’exemple suivant montre comment utiliser l’URL pré-signée pour renseigner votre réponse en modifiant les valeurs d’en-tête selon les besoins avant de renvoyer le code JSON.
Utilisation de requêtes ListObjects
dans Lambda
Cette section suppose que votre point d’accès Object Lambda est configuré pour appeler la fonction Lambda pour ListObjects
. Lambda recevra la charge utile JSON avec un nouvel objet nommé listObjectsContext
. listObjectsContext
contient une propriété unique, inputS3Url
, qui est une URL pré-signée pour le point d’accès de prise en charge pour ListObjects
.
Contrairement à GetObject
et HeadObject
, l’URL pré-signée inclura les propriétés suivantes si elles sont spécifiées :
-
Tous les paramètres de la requête
-
requestPayer
(dans l’en-têtex-amz-request-payer
) -
expectedBucketOwner
(dans l’en-têtex-amz-expected-bucket-owner
)
Pour les paramètres d’URI de la syntaxe de la demande, consultez ListObjects
dans la Référence des API Amazon Simple Storage Service.
Important
Nous vous recommandons d’utiliser la version plus récente, ListObjectsV2, lors du développement d’applications. Pour assurer la compatibilité descendante, Amazon S3 continue de prendre en charge ListObjects
.
L’exemple suivant illustre la charge utile d’entrée JSON de Lambda pour 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" }
Votre fonction Lambda devrait renvoyer un objet JSON contenant le code de statut, le résultat XML de liste ou les informations d’erreur qui seront renvoyées de S3 Object Lambda.
S3 Object Lambda ne traite ni ne valide listResultXml
, mais les transmet à l’appelant ListObjects
. Pour listBucketResult
, S3 Object Lambda s’attend à ce que certaines propriétés soient d’un type spécifique et lèvera des exceptions s’il ne peut pas les analyser. listResultXml
et listBucketResult
ne peuvent pas être fournies en même temps.
L’exemple suivant montre comment utiliser l’URL pré-signée pour appeler Amazon S3 et comment utiliser le résultat pour renseigner une réponse ainsi que vérifier les erreurs.
L’exemple suivant illustre la structure du code JSON de réponse de Lambda pour 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' }, ... ], } }
Utilisation de requêtes ListObjectsV2
dans Lambda
Cette section suppose que votre point d’accès Object Lambda est configuré pour appeler la fonction Lambda pour ListObjectsV2
. Lambda recevra la charge utile JSON avec un nouvel objet nommé listObjectsV2Context
. listObjectsV2Context
contient une propriété unique, inputS3Url
, qui est une URL pré-signée pour le point d’accès de prise en charge pour ListObjectsV2
.
Contrairement à GetObject
et HeadObject
, l’URL pré-signée inclura les propriétés suivantes, si elles sont spécifiées :
-
Tous les paramètres de la requête
-
requestPayer
(dans l’en-têtex-amz-request-payer
) -
expectedBucketOwner
(dans l’en-têtex-amz-expected-bucket-owner
)
Pour les paramètres d’URI de la syntaxe de la demande, consultez ListObjectsV2
dans la Référence des API Amazon Simple Storage Service.
L’exemple suivant illustre la charge utile d’entrée JSON de Lambda pour 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" }
Votre fonction Lambda devrait renvoyer un objet JSON contenant le code de statut, le résultat XML de liste ou les informations d’erreur qui seront renvoyées de S3 Object Lambda.
S3 Object Lambda ne traite ni ne valide listResultXml
, mais les transmet à l’appelant ListObjectsV2
. Pour listBucketResult
, S3 Object Lambda s’attend à ce que certaines propriétés soient d’un type spécifique et lèvera des exceptions s’il ne peut pas les analyser. listResultXml
et listBucketResult
ne peuvent pas être fournies en même temps.
L’exemple suivant montre comment utiliser l’URL pré-signée pour appeler Amazon S3 et comment utiliser le résultat pour renseigner une réponse ainsi que vérifier les erreurs.
L’exemple suivant illustre la structure du code JSON de réponse de Lambda pour 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' }, ... ], } }