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.
Rubriques
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 fichier JavaScript .js ou .mjs. 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, consultez Désignation d’un gestionnaire de fonctions en tant que module 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.
Note
Cet exemple utilise un gestionnaire de modules ES. Lambda prend en charge à la fois le module ES et les gestionnaires CommonJS. Pour de plus amples informations, consultez Désignation d’un gestionnaire de fonctions en tant que module ES.
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. -
Bloc de commentaires JSDoc : définissez les types d’entrée et de sortie pour votre gestionnaire à l’aide d’annotations JSDoc
. -
export const handler: le gestionnaire de la fonction principal que Lambda invoque. Lorsque vous déployez votre fonction, spécifiezindex.handlerpour la propriété Gestionnaire. La valeur de la propriétéHandlerest 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.
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)
-
Ouvrez la page Fonctions
de la console Lambda et choisissez votre fonction. -
Cliquez sur l’onglet Code.
-
Faites défiler l’écran jusqu’au volet Paramètres d’exécution et choisissez Modifier.
-
Dans Gestionnaire, saisissez le nouveau nom de votre gestionnaire de fonction.
-
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 de l’événement d’entrée attendu sous la forme d’annotations JSDoc. Dans cet exemple, nous définissons la structure d’entrée dans le commentaire JSDoc 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 commentaire JSDoc, 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 fonction au lieu d’utiliser des rappels. Async/await est un moyen concis et lisible d’écrire du code asynchrone, 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.
Utilisation d’async/await (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 :
-
event: contient les données d’entrée transmises à votre fonction. -
context: contient des informations sur l’invocation, la fonction et l’environnement d’exécution. Pour de plus amples informations, consultez Utilisation de l’objet de contexte Lambda pour récupérer les informations de la fonction Node.js.
Voici les signatures valides pour le modèle async/await :
export const handler = async(event)=> { };export const handler = async(event, context)=> { };
Note
Utilisez un environnement de développement intégré (IDE) local ou un éditeur de texte pour écrire le code de votre fonction TypeScript. Vous ne pouvez pas créer de code TypeScript sur la console Lambda.
Utilisation de callbacks
Les gestionnaires de 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
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 JavaScript v3 dans votre gestionnaire
Vous utiliserez souvent les fonctions Lambda pour interagir avec d’autres ressources AWS 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 Node.js Lambda pris en charge incluent le SDK pour JavaScript version 3. Cependant, nous vous recommandons vivement d’inclure les clients de SDK AWS 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 service AWS. L’exemple de code appelle l’action d’API Amazon S3 PutObject 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 d’exécution AWS Lambda contient un certain nombre de bibliothèques. Pour les environnements d’exécution Node.js et Python, ceux-ci incluent les kits SDK AWS. 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 relatifs à l’environnement 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 d’API non publiques non documentées dans le code de votre fonction Lambda. Pour les exécutions gérées AWS Lambda, Lambda applique périodiquement des mises à jour de sécurité et fonctionnelles aux API internes de Lambda. Ces mises à jour internes de l’API peuvent être incompatibles avec les versions antérieures, entraînant des conséquences imprévues telles que des échecs d’invocation si votre fonction dépend de ces API non publiques. Consultez la Référence d’API pour obtenir la liste des API accessibles au public.
É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 ?