Définissez le gestionnaire de fonctions Lambda dans TypeScript - AWS Lambda

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.

Définissez le gestionnaire de fonctions Lambda dans TypeScript

Le gestionnaire de fonction Lambda est la méthode dans votre code de fonction qui traite les événements. Lorsque votre fonction est invoquée, Lambda exécute la méthode du gestionnaire. Votre fonction s’exécute jusqu’à ce que le gestionnaire renvoie une réponse, se ferme ou expire.

Notions de base sur le gestionnaire Typescript

Exemple TypeScript gestionnaire

Cet exemple de fonction enregistre le contenu de l'objet événement et renvoie l'emplacement des journaux. Notez ce qui suit :

  • Avant d'utiliser ce code dans une fonction Lambda, vous devez ajouter le package @types/aws-lambda en tant que dépendance de développement. Ce package contient les définitions de type pour Lambda. Quand @types/aws-lambda est installé, l'instruction import (import ... from 'aws-lambda') importe les définitions de type. Il n'importe pas le aws-lambda NPM package, qui est un outil tiers indépendant. Pour plus d'informations, consultez aws-lambda dans le référentiel. DefinitelyTyped GitHub

  • Dans cet exemple, le gestionnaire est un module ES et doit être désigné comme tel dans votre fichier package.json ou en utilisant l'extension de fichier .mjs. Pour plus d'informations, consultez Désignation d’un gestionnaire de fonctions en tant que module ES.

import { Handler } from 'aws-lambda'; export const handler: Handler = async (event, context) => { console.log('EVENT: \n' + JSON.stringify(event, null, 2)); return context.logStreamName; };

L’exécution transmet des arguments à la méthode du gestionnaire. Le premier argument est l’objet event, qui contient les informations de l’appelant. L'invocateur transmet ces informations sous forme de chaîne JSON formatée lorsqu'il appelle Invoke, et le moteur d'exécution les convertit en objet. Lorsqu'un AWS service invoque votre fonction, la structure de l'événement varie d'un service à l'autre. Avec TypeScript, nous vous recommandons d'utiliser des annotations de type pour l'objet d'événement. Pour de plus amples informations, veuillez consulter Utilisation de types pour l'objet d'événement.

Le deuxième argument est l'objet de contexte, qui contient des informations sur l'invocation, la fonction et l'environnement d'exécution. Dans l’exemple précédent, la fonction obtient le nom du flux de journaux de l’objet de contexte et le renvoie au mécanisme d’invocation.

Vous pouvez également utiliser un argument callback, qui est une fonction que vous pouvez appeler dans les gestionnaires non asynchrones pour envoyer une réponse. Nous vous recommandons d’utiliser async/await plutôt que des callbacks. Async/await améliore la lisibilité, la gestion des erreurs et l’efficacité. Pour plus d’informations sur les différences entre async/await et les callbacks, consultez Utilisation de callbacks.

Utilisation d’async/await

Si votre code exécute une tâche asynchrone, utilisez le modèle async/await pour vous assurer que le gestionnaire termine son exécution. Async/await est un moyen concis et lisible d’écrire du code asynchrone dans Node.js, sans avoir besoin de callbacks imbriqués ou de promesses en chaîne. Avec async/await, vous pouvez écrire du code qui se lit comme du code synchrone, tout en étant asynchrone et non bloquant.

Le mot-clé async marque une fonction comme étant asynchrone, et le mot-clé await met en pause l’exécution de la fonction jusqu’à ce qu’une Promise soit résolue.

Exemple TypeScript fonction — asynchrone

Cet exemple utilise fetch, qui est disponible dans l’exécution nodejs18.x. Notez ce qui suit :

  • Avant d'utiliser ce code dans une fonction Lambda, vous devez ajouter le package @types/aws-lambda en tant que dépendance de développement. Ce package contient les définitions de type pour Lambda. Quand @types/aws-lambda est installé, l'instruction import (import ... from 'aws-lambda') importe les définitions de type. Il n'importe pas le aws-lambda NPM package, qui est un outil tiers indépendant. Pour plus d'informations, consultez aws-lambda dans le référentiel. DefinitelyTyped GitHub

  • Dans cet exemple, le gestionnaire est un module ES et doit être désigné comme tel dans votre fichier package.json ou en utilisant l'extension de fichier .mjs. Pour plus d'informations, consultez Désignation d’un gestionnaire de fonctions en tant que module ES.

import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'; const url = 'https://aws.amazon.com/'; export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => { try { // fetch is available with Node.js 18 const res = await fetch(url); return { statusCode: res.status, body: JSON.stringify({ message: await res.text(), }), }; } catch (err) { console.log(err); return { statusCode: 500, body: JSON.stringify({ message: 'some error happened', }), }; } };

Utilisation de callbacks

Nous vous recommandons d’utiliser async/await pour déclarer le gestionnaire de fonctions au lieu d’utiliser des callbacks. Async/await est un meilleur choix pour plusieurs raisons :

  • Lisibilité : le code Async/await est plus facile à lire et à comprendre que le code callback, qui peut rapidement devenir difficile à suivre et entraîner l’enfer du callback.

  • Débogage et gestion des erreurs : le débogage du code basé sur des callbacks peut être difficile. La pile d’appels peut devenir difficile à suivre et les erreurs peuvent facilement se perdre. Avec async/await, vous pouvez utiliser des blocs try/catch pour gérer les erreurs.

  • Efficacité : les callbacks nécessitent souvent de basculer entre différentes parties du code. Async/await permet de réduire le nombre de changements de contexte, ce qui se traduit par un code plus efficace.

Lorsque vous utilisez des callbacks dans votre gestionnaire, la fonction continue à s’exécuter jusqu’à ce que la boucle d’événement soit vide ou que la fonction s’arrête. La réponse n’est pas envoyée à l’appelant tant que toutes les tâches d’événement de boucle ne sont pas terminées. Si la fonction expire, une erreur est renvoyée à la place. Vous pouvez configurer le moteur d'exécution pour envoyer la réponse immédiatement en définissant le contexte. callbackWaitsForEmptyEventLoopà faux.

La fonction de rappel accepte deux arguments : un(e) Error et une réponse. L’objet de réponse doit être compatible avec JSON.stringify.

Exemple TypeScript fonction avec rappel

Cet exemple de fonction reçoit un événement d'Amazon API Gateway, enregistre l'événement et les objets de contexte, puis renvoie une réponse à API Gateway. Notez ce qui suit :

  • Avant d'utiliser ce code dans une fonction Lambda, vous devez ajouter le package @types/aws-lambda en tant que dépendance de développement. Ce package contient les définitions de type pour Lambda. Quand @types/aws-lambda est installé, l'instruction import (import ... from 'aws-lambda') importe les définitions de type. Il n'importe pas le aws-lambda NPM package, qui est un outil tiers indépendant. Pour plus d'informations, consultez aws-lambda dans le référentiel. DefinitelyTyped GitHub

  • Dans cet exemple, le gestionnaire est un module ES et doit être désigné comme tel dans votre fichier package.json ou en utilisant l'extension de fichier .mjs. Pour plus d'informations, consultez Désignation d’un gestionnaire de fonctions en tant que module ES.

import { Context, APIGatewayProxyCallback, APIGatewayEvent } from 'aws-lambda'; export const lambdaHandler = (event: APIGatewayEvent, context: Context, callback: APIGatewayProxyCallback): void => { console.log(`Event: ${JSON.stringify(event, null, 2)}`); console.log(`Context: ${JSON.stringify(context, null, 2)}`); callback(null, { statusCode: 200, body: JSON.stringify({ message: 'hello world', }), }); };

Utilisation de types pour l'objet d'événement

Nous vous recommandons de ne pas utiliser le type Any (Tout) pour les arguments du gestionnaire et du type de retour, car vous perdez la possibilité de vérifier les types. Générez plutôt un événement à l'aide de la AWS Serverless Application Model CLI commande sam local generate-event ou utilisez une définition open source du package @types /aws-lambda.

Génération d'un événement à l'aide de la commande sam local generate-event (génération d'événement local sam)
  1. Générez un événement proxy Amazon Simple Storage Service (Amazon S3).

    sam local generate-event s3 put >> S3PutEvent.json
  2. Utilisez l'utilitaire quicktype pour générer des définitions de type à partir du PutEventfichier .json S3.

    npm install -g quicktype quicktype S3PutEvent.json -o S3PutEvent.ts
  3. Utilisez les types générés dans votre code.

    import { S3PutEvent } from './S3PutEvent'; export const lambdaHandler = async (event: S3PutEvent): Promise<void> => { event.Records.map((record) => console.log(record.s3.object.key)); };
Génération d'un événement à l'aide d'une définition Open source à partir du pack @types/aws-lambda
  1. Ajoutez le pack @types/aws-lambda en tant que dépendance de développement.

    npm install -D @types/aws-lambda
  2. Utilisez les types dans votre code.

    import { S3Event } from "aws-lambda"; export const lambdaHandler = async (event: S3Event): Promise<void> => { event.Records.map((record) => console.log(record.s3.object.key)); };

Meilleures pratiques en matière de code pour les fonctions Typescript Lambda

Respectez les directives de la liste suivante pour utiliser les meilleures pratiques de codage lors de la création de vos fonctions Lambda :

  • Séparez le gestionnaire Lambda de votre logique principale. Cela vous permet de créer une fonction testable plus unitaire. Dans Node.js, vous obtenez ce qui suit :

    exports.myHandler = function(event, context, callback) { var foo = event.foo; var bar = event.bar; var result = MyLambdaFunction (foo, bar); callback(null, result); } function MyLambdaFunction (foo, bar) { // MyLambdaFunction logic here }
  • Contrôlez les dépendances du package de déploiement de vos fonctions. L'environnement AWS Lambda d'exécution contient un certain nombre de bibliothèques. Pour les environnements d'exécution Node.js et Python, ceux-ci incluent le AWS SDKs. Pour activer le dernier ensemble de mises à jour des fonctionnalités et de la sécurité, Lambda met régulièrement à jour ces bibliothèques. Ces mises à jour peuvent introduire de subtiles modifications dans le comportement de votre fonction Lambda. Pour disposer du contrôle total des dépendances que votre fonction utilise, empaquetez toutes vos dépendances avec votre package de déploiement.

  • Réduisez la complexité de vos dépendances. Privilégiez les infrastructures plus simples qui se chargent rapidement au démarrage de l’environnement d’exécution.

  • Réduisez la taille de votre package de déploiement selon ses besoins d’exécution. Cela contribue à réduire le temps nécessaire au téléchargement et à la décompression de votre package de déploiement avant l’invocation.

  • Tirez parti de la réutilisation de l’environnement d’exécution pour améliorer les performances de votre fonction. Initialisez les SDK clients et les connexions à la base de données en dehors du gestionnaire de fonctions et mettez en cache les actifs statiques localement dans le /tmp répertoire. Les invocations ultérieures traitées par la même instance de votre fonction peuvent réutiliser ces ressources. Cela permet d’économiser des coûts, tout en réduisant le temps d’exécution de la fonction.

    Pour éviter des éventuelles fuites de données entre les invocations, n’utilisez pas l’environnement d’exécution pour stocker des données utilisateur, des événements ou d’autres informations ayant un impact sur la sécurité. Si votre fonction repose sur un état réversible qui ne peut pas être stocké en mémoire dans le gestionnaire, envisagez de créer une fonction distincte ou des versions distinctes d’une fonction pour chaque utilisateur.

  • Utilisez une directive keep-alive pour maintenir les connexions persistantes. Lambda purge les connexions inactives au fil du temps. Si vous tentez de réutiliser une connexion inactive lorsque vous invoquez une fonction, cela entraîne une erreur de connexion. Pour maintenir votre connexion persistante, utilisez la directive Keep-alive associée à votre environnement d’exécution. Pour obtenir un exemple, consultez Réutilisation des connexions avec Keep-Alive dans Node.js.

  • Utilisez des variables d’environnement pour transmettre des paramètres opérationnels à votre fonction. Par exemple, si vous écrivez dans un compartiment Amazon S3 au lieu de coder en dur le nom du compartiment dans lequel vous écrivez, configurez le nom du compartiment comme variable d’environnement.

  • Évitez d'utiliser des invocations récursives dans votre fonction Lambda, lorsque la fonction s'invoque elle-même ou initie un processus susceptible de l'invoquer à nouveau. Cela peut entraîner un volume involontaire d’invocations de fonction et des coûts accrus. Si vous constatez un volume d'invocations involontaire, réglez la fonction réservée à la simultanéité sur 0 immédiatement afin de limiter toutes les invocations à la fonction pendant que vous mettez à jour le code.

  • N'utilisez pas de code non documenté ni public APIs dans votre code de fonction Lambda. Pour les AWS Lambda environnements d'exécution gérés, Lambda applique régulièrement des mises à jour de sécurité et fonctionnelles aux applications internes de Lambda. APIs Ces API mises à jour internes peuvent être rétroincompatibles, ce qui peut entraîner des conséquences imprévues, telles que des échecs d'invocation si votre fonction dépend de ces mises à jour non publiques. APIs Voir la API référence pour une liste des documents accessibles au publicAPIs.

  • Écriture du code idempotent. L’écriture de code idempotent pour vos fonctions garantit ne gestion identique des événements dupliqués. Votre code doit valider correctement les événements et gérer correctement les événements dupliqués. Pour de plus amples informations, veuillez consulterComment faire en sorte que ma fonction Lambda soit idempotente ?.