Définition du gestionnaire de fonction Lambda dans Node.js - 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éfinition du gestionnaire de fonction Lambda dans Node.js

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.

Cette page explique comment utiliser les gestionnaires de fonctions Lambda dans Node.js, notamment des options pour la configuration du projet, les conventions de dénomination et les pratiques exemplaires. Cette page inclut également un exemple de fonction Lambda Node.js qui collecte des informations relatives à une commande, produit un reçu sous forme de fichier texte et place ce fichier dans un compartiment Amazon Simple Storage Service (Amazon S3). Pour plus d’informations sur le déploiement de votre fonction après l’avoir écrite, consultez Déployer des fonctions Lambda en Node.js avec des archives de fichiers .zip ou Déployer des fonctions Lambda en Node.js avec des images conteneurs.

Configuration de votre projet de gestionnaire Node.js

Il existe plusieurs façons d’initialiser un projet Node.js Lambda. Par exemple, vous pouvez créer un projet Node.js standard en utilisant npm, créer une application AWS SAM ou créer une application AWS CDK.

Pour créer le projet avec npm :

npm init

Cette commande initialise votre projet et génère un fichier package.json qui gère les métadonnées et dépendances de votre projet.

Le code de votre fonction se trouve dans un .mjs JavaScript fichier .js or. Dans l’exemple suivant, nous nommons ce fichier index.mjs, car il utilise un gestionnaire de modules ES. Lambda prend en charge à la fois le module ES et les gestionnaires CommonJS. Pour de plus amples informations, veuillez consulter Modules CommonJS et ES.

Un projet de fonction Lambda Node.js typique suit cette structure générale :

/project-root ├── index.mjs — Contains main handler ├── package.json — Project metadata and dependencies ├── package-lock.json — Dependency lock file └── node_modules/ — Installed dependencies

Exemple de fonction Lambda Node.js

L’exemple de code de fonction Lambda suivant prend en compte les informations relatives à une commande, produit un reçu sous forme de fichier texte et place ce fichier dans un compartiment Amazon S3.

Exemple index.mjs, fonction Lambda
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'; // Initialize the S3 client outside the handler for reuse const s3Client = new S3Client(); /** * Lambda handler for processing orders and storing receipts in S3. * @param {Object} event - Input event containing order details * @param {string} event.order_id - The unique identifier for the order * @param {number} event.amount - The order amount * @param {string} event.item - The item purchased * @returns {Promise<string>} Success message */ export const handler = async(event) => { try { // Access environment variables const bucketName = process.env.RECEIPT_BUCKET; if (!bucketName) { throw new Error('RECEIPT_BUCKET environment variable is not set'); } // Create the receipt content and key destination const receiptContent = `OrderID: ${event.order_id}\nAmount: $${event.amount.toFixed(2)}\nItem: ${event.item}`; const key = `receipts/${event.order_id}.txt`; // Upload the receipt to S3 await uploadReceiptToS3(bucketName, key, receiptContent); console.log(`Successfully processed order ${event.order_id} and stored receipt in S3 bucket ${bucketName}`); return 'Success'; } catch (error) { console.error(`Failed to process order: ${error.message}`); throw error; } }; /** * Helper function to upload receipt to S3 * @param {string} bucketName - The S3 bucket name * @param {string} key - The S3 object key * @param {string} receiptContent - The content to upload * @returns {Promise<void>} */ async function uploadReceiptToS3(bucketName, key, receiptContent) { try { const command = new PutObjectCommand({ Bucket: bucketName, Key: key, Body: receiptContent }); await s3Client.send(command); } catch (error) { throw new Error(`Failed to upload receipt to S3: ${error.message}`); } }

Ce fichier index.mjs comprend les sections suivantes :

  • Bloc import : utilisez ce bloc pour inclure les bibliothèques que votre fonction Lambda requiert, comme les clients du SDK AWS.

  • Déclaration const s3Client : initialise un client Amazon S3 en dehors de la fonction du gestionnaire. Lambda exécute donc ce code pendant la phase d’initialisation, et le client est conservé pour être réutilisé lors de plusieurs appels.

  • JSDoc bloc de commentaires : définissez les types d'entrée et de sortie pour votre gestionnaire à l'aide d'JSDoc annotations.

  • export const handler : le gestionnaire de la fonction principal que Lambda invoque. Lorsque vous déployez votre fonction, spécifiez index.handler pour la propriété Gestionnaire. La valeur de la propriété Handler est le nom du fichier et le nom de la méthode du gestionnaire exporté, séparés par un point.

  • Fonction uploadReceiptToS3 : une fonction d’assistance référencée par la fonction du gestionnaire principal.

Pour que cette fonction fonctionne correctement, son rôle d’exécution doit autoriser l’action s3:PutObject. Assurez-vous également de définir la variable d’environnement RECEIPT_BUCKET. Après une invocation réussie, le compartiment Amazon S3 doit contenir un fichier de reçu.

Modules CommonJS et ES

Node.js prend en charge deux systèmes de modules : CommonJS et ECMAScript modules (modules ES). Lambda recommande d'utiliser les modules ES car ils prennent en charge l'attente de haut niveau, ce qui permet d'effectuer des tâches asynchrones lors de l'initialisation de l'environnement d'exécution.

Node.js traite les fichiers avec une extension de nom de .cjs fichier comme des modules CommonJS tandis qu'une .mjs extension désigne les modules ES. Par défaut, Node.js traite les fichiers portant l'extension de nom de .js fichier comme des modules CommonJS. Vous pouvez configurer Node.js pour traiter les .js fichiers comme des modules ES en spécifiant le type as module dans le package.json fichier de la fonction. Vous pouvez configurer Node.js dans Lambda pour détecter automatiquement si un .js fichier doit être traité comme CommonJS ou comme un module ES en ajoutant l'—experimental-detect-moduleindicateur à la NODE_OPTIONS variable d'environnement. Pour plus d'informations, consultez la section Fonctionnalités expérimentales de Node.js.

Les exemples suivants montrent des gestionnaires de fonctions écrits à l'aide de modules ES et de modules CommonJS. Les autres exemples de cette page utilisent tous des modules ES.

ES module example
Exemple – Gestionnaire de modules ES
const url = "https://aws.amazon.com/"; export const handler = async(event) => { try { const res = await fetch(url); console.info("status", res.status); return res.status; } catch (e) { console.error(e); return 500; } };
CommonJS module example
Exemple – Gestionnaire de modules CommonJS
const https = require("https"); let url = "https://aws.amazon.com/"; exports.handler = async function (event) { let statusCode; await new Promise(function (resolve, reject) { https.get(url, (res) => { statusCode = res.statusCode; resolve(statusCode); }).on("error", (e) => { reject(Error(e)); }); }); console.log(statusCode); return statusCode; };

Initialisation de Node.js

Node.js utilise un I/O modèle non bloquant qui prend en charge des opérations asynchrones efficaces à l'aide d'une boucle d'événements. Par exemple, si Node.js effectue un appel réseau, la fonction continue de traiter les autres opérations sans bloquer une réponse réseau. Lorsque la réponse du réseau est reçue, elle est placée dans la file de rappel. Les tâches de la file d'attente sont traitées lorsque la tâche en cours est terminée.

Lambda recommande d'utiliser l'attente de haut niveau afin que les tâches asynchrones initiées lors de l'initialisation de l'environnement d'exécution soient terminées pendant l'initialisation. Les tâches asynchrones qui ne sont pas terminées lors de l'initialisation s'exécutent généralement lors du premier appel de fonction. Cela peut entraîner un comportement inattendu ou des erreurs. Par exemple, l'initialisation de votre fonction peut effectuer un appel réseau pour récupérer un paramètre depuis le Parameter Store AWS . Si cette tâche n'est pas terminée lors de l'initialisation, la valeur peut être nulle lors d'un appel. Il peut également y avoir un délai entre l'initialisation et l'appel, ce qui peut déclencher des erreurs lors d'opérations sensibles au facteur temps. En particulier, les appels de AWS service peuvent s'appuyer sur des signatures de demande urgentes, ce qui entraîne l'échec des appels de service si l'appel n'est pas terminé pendant la phase d'initialisation. L'exécution des tâches lors de l'initialisation améliore généralement les performances de démarrage à froid et les performances d'appel d'abord lors de l'utilisation de la concurrence provisionnée. Pour plus d'informations, consultez notre article de blog Using Node.js ES modules and top-level await in AWS Lambda.

Convention de nommage du gestionnaire

Lorsque vous configurez une fonction, la valeur du paramètre Gestionnaire est le nom du fichier et le nom de la méthode du gestionnaire exporté, séparés par un point. La valeur par défaut des fonctions créées dans la console et dans les exemples de ce guide est index.handler. Cela indique la méthode handler qui est exportée à partir du fichier index.js ou index.mjs.

Si vous créez une fonction dans la console en utilisant un nom de fichier ou un nom de gestionnaire de fonction différent, vous devez modifier le nom du gestionnaire par défaut.

Pour modifier le nom du gestionnaire de fonction (console)
  1. Ouvrez la page Fonctions de la console Lambda et choisissez votre fonction.

  2. Cliquez sur l’onglet Code.

  3. Faites défiler l’écran jusqu’au volet Paramètres d’exécution et choisissez Modifier.

  4. Dans Gestionnaire, saisissez le nouveau nom de votre gestionnaire de fonction.

  5. Choisissez Enregistrer.

Définition et accès à l’objet d’événement d’entrée

JSON est le format d’entrée le plus courant et standard pour les fonctions Lambda. Dans cet exemple, la fonction exige une entrée similaire à l’exemple suivant :

{ "order_id": "12345", "amount": 199.99, "item": "Wireless Headphones" }

Lorsque vous utilisez des fonctions Lambda dans Node.js, vous pouvez définir la forme attendue de l'événement d'entrée à l'aide JSDoc d'annotations. Dans cet exemple, nous définissons la structure de saisie dans le JSDoc commentaire du gestionnaire :

/** * Lambda handler for processing orders and storing receipts in S3. * @param {Object} event - Input event containing order details * @param {string} event.order_id - The unique identifier for the order * @param {number} event.amount - The order amount * @param {string} event.item - The item purchased * @returns {Promise<string>} Success message */

Après avoir défini ces types dans votre JSDoc commentaire, vous pouvez accéder aux champs de l'objet d'événement directement dans votre code. Par exemple, event.order_id récupère la valeur de order_id à partir de l’entrée d’origine.

Modèles de gestionnaire valides pour les fonctions Node.js

Nous vous recommandons d'utiliser async/await pour déclarer le gestionnaire de fonctions au lieu d'utiliser des rappels. Async/await est un moyen concis et lisible d'écrire du code asynchrone, sans avoir besoin de rappels imbriqués ou de promesses enchaînées. Avec async/await, vous pouvez écrire du code qui se lit comme du code synchrone, tout en étant asynchrone et non bloquant.

gestionnaires de fonctions asynchrones (recommandé)

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. Le gestionnaire accepte les arguments suivants :

Voici les signatures valides pour le async/await modèle :

export const handler = async (event) => { };
export const handler = async (event, context) => { };

Gestionnaires de fonctions synchrones

Lorsque votre fonction n'exécute aucune tâche asynchrone, vous pouvez utiliser un gestionnaire de fonctions synchrones en utilisant l'une des signatures de fonction suivantes :

export const handler = (event) => { };
export const handler = (event, context) => { };

Gestionnaires de fonctions de diffusion des réponses

Lambda prend en charge le streaming des réponses avec Node.js. Les gestionnaires de fonctions de streaming de réponses utilisent le awslambda.streamifyResponse() décorateur et prennent 3 paramètres : eventresponseStream, et. context La signature de la fonction est la suivante :

export const handler = awslambda.streamifyResponse(async (event, responseStream, context) => { });

Pour de plus amples informations, veuillez consulter Streaming de réponses pour les fonctions Lambda.

Gestionnaires de fonctions basés sur le rappel

Note

Les gestionnaires de fonctions basés sur le rappel ne sont pris en charge que jusqu'à Node.js 22. À partir de Node.js 24, les tâches asynchrones doivent être implémentées à l'aide de gestionnaires de fonctions asynchrones.

Les gestionnaires de fonctions basés sur le rappel doivent utiliser les arguments d'événement, de contexte et de rappel. Exemple :

export const handler = (event, context, callback) => { };

La fonction de rappel attend une Error et une réponse, qui doit être sérialisable en JSON. 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.

Exemple – Requête HTTP avec callback

L’exemple suivant vérifie la fonction d’une URL et renvoie le code de statut au mécanisme d’appel.

import https from "https"; let url = "https://aws.amazon.com/"; export const handler = (event, context, callback) => { https.get(url, (res) => { callback(null, res.statusCode); }).on("error", (e) => { callback(Error(e)); }); };

Utilisation du SDK pour la JavaScript version 3 dans votre gestionnaire

Vous utiliserez souvent les fonctions Lambda pour interagir avec d'autres AWS ressources ou pour les mettre à jour. Le moyen le plus simple d’interagir avec ces ressources est d’utiliser AWS SDK pour JavaScript. Tous les environnements d'exécution Lambda Node.js pris en charge incluent le SDK pour la version 3. JavaScript Toutefois, nous vous recommandons vivement d'inclure les clients AWS SDK dont vous avez besoin dans votre package de déploiement. Cela permet d’optimiser la rétrocompatibilité lors des futures mises à jour de l’environnement d’exécution Lambda. Ne vous fiez au SDK fourni par l'environnement d'exécution que lorsque vous ne pouvez pas inclure de packages supplémentaires (par exemple, lorsque vous utilisez l'éditeur de code de la console Lambda ou du code en ligne dans un modèle). AWS CloudFormation

Pour ajouter des dépendances au SDK à votre fonction, utilisez la commande npm install correspondant aux clients SDK spécifiques dont vous avez besoin. Dans l’exemple de code, nous avons utilisé le client Amazon S3. Ajoutez cette dépendance en exécutant la commande suivante dans le répertoire qui contient votre fichier package.json :

npm install @aws-sdk/client-s3

Dans le code de fonction, importez le client et les commandes dont vous avez besoin, comme le montre l’exemple de fonction :

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

Initialisez ensuite un client Amazon S3 :

const s3Client = new S3Client();

Dans cet exemple, nous avons initialisé notre client Amazon S3 en dehors de la fonction de gestionnaire principale pour éviter d’avoir à l’initialiser à chaque fois que nous invoquons notre fonction. Après avoir initialisé votre client SDK, vous pouvez l'utiliser pour effectuer des appels d'API pour ce AWS service. L'exemple de code appelle l'action d'PutObjectAPI Amazon S3 comme suit :

const command = new PutObjectCommand({ Bucket: bucketName, Key: key, Body: receiptContent });

Accès aux variables d’environnement

Dans le code de votre gestionnaire, vous pouvez référencer n’importe quelle variable d’environnement à l’aide de process.env. Dans cet exemple, nous référençons la variable d’environnement RECEIPT_BUCKET définie à l’aide des lignes de code suivantes :

// Access environment variables const bucketName = process.env.RECEIPT_BUCKET; if (!bucketName) { throw new Error('RECEIPT_BUCKET environment variable is not set'); }

Utilisation de l'état global

Lambda exécute votre code statique pendant la phase d’initialisation avant d’invoquer votre fonction pour la première fois. Les ressources créées pendant l’initialisation restent en mémoire entre les invocations, ce qui vous évite d’avoir à les créer chaque fois que vous invoquez votre fonction.

Dans l’exemple de code, le code d’initialisation du client S3 se trouve en dehors du gestionnaire. L’exécution initialise le client avant que la fonction n’exécute son premier événement, et le client reste disponible pour être réutilisé pendant toutes les invocations.

Pratiques exemplaires en matière de code pour les fonctions Lambda Node.js

Suivez ces instructions pour créer des fonctions Lambda :

  • Séparez le gestionnaire Lambda de votre logique principale. Cela vous permet de créer une fonction testable plus unitaire.

  • 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 clients SDK et les connexions à la base de données en dehors du gestionnaire de fonctions et mettez en cache les actifs statiques localement dans le répertoire /tmp. 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 démarre 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 involontaire d’invocations, définissez immédiatement la simultanéité réservée à la fonction sur 0 afin de limiter toutes les invocations de 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 mises à jour internes de l'API 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 Consultez la référence de l'API pour obtenir une liste des API accessibles au public APIs.

É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 ?.