Aller au contenu

Fonction Lambda TypeScript

Le générateur de fonction Lambda TypeScript permet d’ajouter une fonction lambda à un projet TypeScript existant.

Ce générateur crée un nouveau gestionnaire Lambda TypeScript avec une infrastructure AWS CDK ou Terraform. Le gestionnaire généré utilise AWS Lambda Powertools for TypeScript pour l’observabilité, incluant la journalisation, le traçage AWS X-Ray et les métriques CloudWatch, ainsi qu’une sécurité de type optionnelle pour les événements grâce au Parser d’AWS Lambda Powertools.

Vous pouvez générer une fonction lambda de deux manières :

  1. Installez le Nx Console VSCode Plugin si ce n'est pas déjà fait
  2. Ouvrez la console Nx dans VSCode
  3. Cliquez sur Generate (UI) dans la section "Common Nx Commands"
  4. Recherchez @aws/nx-plugin - ts#lambda-function
  5. Remplissez les paramètres requis
    • Cliquez sur Generate
    Paramètre Type Par défaut Description
    project Requis string - The project to add the lambda function to
    functionName Requis string - The name of the function to add
    functionPath string - Optional subdirectory within the project source directory to add the function to
    eventSource string Any Optional event source schema to use for the lambda function
    iacProvider string Inherit The preferred IaC provider. By default this is inherited from your initial selection.

    Le générateur ajoutera les fichiers suivants à votre projet :

    • Répertoire<project-name>
      • Répertoiresrc/
        • <lambda-function>.ts Implémentation de la fonction

    Si l’option functionPath est spécifiée, le générateur ajoutera le gestionnaire au chemin indiqué dans le répertoire source du projet :

    • Répertoire<project-name>
      • Répertoiresrc/
        • Répertoire<custom-path>/
          • <function-name>.ts Implémentation de la fonction

    Ce générateur fournit de l’infrastructure as code basée sur votre iacProvider choisi. Il créera un projet dans packages/common qui inclut les constructions CDK ou modules Terraform pertinents.

    Le projet commun d’infrastructure as code est structuré comme suit :

    • Répertoirepackages/common/constructs
      • Répertoiresrc
        • Répertoireapp/ Constructions pour l’infrastructure spécifique à un projet/générateur
        • Répertoirecore/ Constructions génériques réutilisées par celles dans app
        • index.ts Point d’entrée exportant les constructions depuis app
      • project.json Cibles de build et configuration du projet

    Le générateur crée une infrastructure-as-code pour déployer votre fonction selon le iacProvider sélectionné :

    Le générateur crée un construct CDK utilisable pour déployer votre fonction, situé dans le répertoire packages/common/constructs/src/app/lambda-functions.

    L’implémentation principale se trouve dans <function-name>.ts. Voici un exemple :

    import { parser } from '@aws-lambda-powertools/parser/middleware';
    import { EventBridgeSchema } from '@aws-lambda-powertools/parser/schemas';
    import middy from '@middy/core';
    import { Tracer } from '@aws-lambda-powertools/tracer';
    import { captureLambdaHandler } from '@aws-lambda-powertools/tracer/middleware';
    import { injectLambdaContext } from '@aws-lambda-powertools/logger/middleware';
    import { Logger } from '@aws-lambda-powertools/logger';
    import { Metrics } from '@aws-lambda-powertools/metrics';
    import { logMetrics } from '@aws-lambda-powertools/metrics/middleware';
    import { z } from 'zod';
    process.env.POWERTOOLS_METRICS_NAMESPACE = 'MyFunction';
    process.env.POWERTOOLS_SERVICE_NAME = 'MyFunction';
    const tracer = new Tracer();
    const logger = new Logger();
    const metrics = new Metrics();
    export const myFunction = async (
    event: z.infer<typeof EventBridgeSchema>,
    ): Promise<void> => {
    logger.info('Received event', event);
    // TODO: implement
    };
    export const handler = middy()
    .use(captureLambdaHandler(tracer))
    .use(injectLambdaContext(logger))
    .use(logMetrics(metrics))
    .use(parser({ schema: EventBridgeSchema }))
    .handler(myFunction);

    Le générateur configure automatiquement plusieurs fonctionnalités :

    1. Pile de middleware Middy pour des fonctionnalités Lambda étendues
    2. Intégration AWS Lambda Powertools pour l’observabilité
    3. Collecte de métriques avec CloudWatch
    4. Sécurité des types via le middleware de parsing
    5. Bundling avec Rolldown pour des packages de déploiement optimisés

    Le générateur configure la journalisation structurée avec AWS Lambda Powertools et l’injection automatique de contexte via le middleware Middy.

    export const handler = middy()
    .use(injectLambdaContext(logger))
    .handler(myFunction);

    Le traçage AWS X-Ray est configuré automatiquement via le middleware captureLambdaHandler. Vous pouvez ajouter des sous-segments personnalisés :

    const tracer = new Tracer();
    export const myFunction = async (
    event: z.infer<typeof EventBridgeSchema>,
    ): Promise<void> => {
    // Crée un nouveau sous-segment
    const subsegment = tracer.getSegment()?.addNewSubsegment('custom-operation');
    try {
    // Votre logique ici
    } catch (error) {
    subsegment?.addError(error as Error);
    throw error;
    } finally {
    subsegment?.close();
    }
    };
    export const handler = middy()
    .use(captureLambdaHandler(tracer))
    .handler(myFunction);

    Les métriques CloudWatch sont collectées automatiquement pour chaque requête via le middleware logMetrics. Vous pouvez ajouter des métriques personnalisées :

    const metrics = new Metrics();
    export const myFunction = async (
    event: z.infer<typeof EventBridgeSchema>,
    ): Promise<void> => {
    metrics.addMetric("CustomMetric", MetricUnit.Count, 1);
    metrics.addMetric("ProcessingTime", MetricUnit.Milliseconds, processingTime);
    };
    export const handler = middy()
    .use(logMetrics(metrics))
    .handler(myFunction);

    Si vous avez choisi un eventSource lors de la génération, votre fonction est instrumentée avec le middleware parser d’AWS Lambda Powertools. Exemple :

    export const myFunction = async (
    event: z.infer<typeof EventBridgeSchema>,
    ): Promise<void> => {
    event.detail // <- typage fort avec autocomplétion IDE
    };
    export const handler = middy()
    .use(parser({ schema: EventBridgeSchema }))
    .handler(myFunction);

    Cela fournit un typage à la compilation et une validation à l’exécution pour les événements Lambda.

    Si vous ne souhaitez pas typer votre événement, sélectionnez Any pour eventSource, ce qui donnera un type any au paramètre event.

    Le générateur configure automatiquement une cible bundle qui utilise Rolldown pour créer un package de déploiement :

    Terminal window
    pnpm nx run <project-name>:bundle

    La configuration de Rolldown se trouve dans rolldown.config.ts, avec une entrée par bundle à générer. Rolldown gère la création de plusieurs bundles en parallèle si définis.

    Ce générateur crée une infrastructure CDK ou Terraform sous forme de code en fonction du iacProvider sélectionné. Vous pouvez l’utiliser pour déployer votre fonction.

    Ce générateur crée un construct CDK pour déployer votre fonction dans le dossier common/constructs. Vous pouvez l’utiliser dans une application CDK :

    import { MyProjectMyFunction } from ':my-scope/common-constructs';
    export class ExampleStack extends Stack {
    constructor(scope: Construct, id: string) {
    // Ajoute la fonction à votre stack
    const fn = new MyProjectMyFunction(this, 'MyFunction');
    }
    }

    Ceci configure :

    1. Une fonction AWS Lambda
    2. Un groupe de logs CloudWatch
    3. La configuration du tracing X-Ray
    4. Un espace de noms pour les métriques CloudWatch

    Cette fonction peut ensuite être utilisée comme cible pour n’importe quelle source d’événement lambda :

    L’exemple ci-dessous montre le code CDK pour invoquer votre fonction lambda selon un calendrier avec EventBridge :

    import { Rule, Schedule } from 'aws-cdk-lib/aws-events';
    import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets';
    import { MyProjectMyFunction } from ':my-scope/common-constructs';
    export class ExampleStack extends Stack {
    constructor(scope: Construct, id: string) {
    // Ajoute la fonction à votre stack
    const fn = new MyProjectMyFunction(this, 'MyFunction');
    // Ajoute la fonction à une règle planifiée EventBridge
    const eventRule = new Rule(this, 'MyFunctionScheduleRule', {
    schedule: Schedule.cron({ minute: '15' }),
    targets: [new LambdaFunction(fn)],
    });
    }
    }