Skip to content

TypeScript Lambda Function

The TypeScript Lambda Function generator provides the ability to add a lambda function to an existing TypeScript project.

This generator creates a new TypeScript lambda handler with AWS CDK or Terraform infrastructure setup. The generated handler uses AWS Lambda Powertools for TypeScript for observability, including logging, AWS X-Ray tracing and CloudWatch Metrics, as well as optional type-safety for the event using the Parser from AWS Lambda Powertools

You can generate a lambda function in two ways:

  1. Install the Nx Console VSCode Plugin if you haven't already
  2. Open the Nx Console in VSCode
  3. Click Generate (UI) in the "Common Nx Commands" section
  4. Search for @aws/nx-plugin - ts#lambda-function
  5. Fill in the required parameters
    • Click Generate
    Parameter Type Default Description
    project Required string - The project to add the lambda function to
    functionName Required 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.

    The generator will add the following files to your project:

    • Directory<project-name>
      • Directorysrc/
        • <lambda-function>.ts Function implementation

    If the functionPath option is provided, the generator will add the handler to the specified path within the project source directory:

    • Directory<project-name>
      • Directorysrc/
        • Directory<custom-path>/
          • <function-name>.ts Function implementation

    Since this generator vends infrastructure as code based on your chosen iacProvider, it will create a project in packages/common which includes the relevant CDK constructs or Terraform modules.

    The common infrastructure as code project is structured as follows:

    • Directorypackages/common/constructs
      • Directorysrc
        • Directoryapp/ Constructs for infrastructure specific to a project/generator
        • Directorycore/ Generic constructs which are reused by constructs in app
        • index.ts Entry point exporting constructs from app
      • project.json Project build targets and configuration

    The generator creates infrastructure as code for deploying your function based on your selected iacProvider:

    The generator creates a CDK construct which can be used to deploy your function, which resides in the packages/common/constructs/src/app/lambda-functions directory.

    The main function implementation is in <function-name>.ts. Here’s an example:

    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);

    The generator sets up several features automatically:

    1. Middy middleware stack for enhanced Lambda functionality
    2. AWS Lambda Powertools integration for observability
    3. Metrics collection with CloudWatch
    4. Type-safety using parser middleware
    5. Bundling with Rolldown for optimized deployment packages

    The generator configures structured logging using AWS Lambda Powertools with automatic context injection via Middy middleware.

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

    AWS X-Ray tracing is configured automatically via the captureLambdaHandler middleware. You can add custom subsegments to your traces:

    const tracer = new Tracer();
    export const myFunction = async (
    event: z.infer<typeof EventBridgeSchema>,
    ): Promise<void> => {
    // Creates a new subsegment
    const subsegment = tracer.getSegment()?.addNewSubsegment('custom-operation');
    try {
    // Your logic here
    } catch (error) {
    subsegment?.addError(error as Error);
    throw error;
    } finally {
    subsegment?.close();
    }
    };
    export const handler = middy()
    .use(captureLambdaHandler(tracer))
    .handler(myFunction);

    CloudWatch metrics are collected automatically for each request via the logMetrics middleware. You can add custom metrics:

    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);

    If you chose an eventSource when generating your lambda function, your function is instrumented with the parser middleware from AWS Lambda Powertools. For example:

    export const myFunction = async (
    event: z.infer<typeof EventBridgeSchema>,
    ): Promise<void> => {
    event.detail // <- type-safe with IDE autocompletion
    };
    export const handler = middy()
    .use(parser({ schema: EventBridgeSchema }))
    .handler(myFunction);

    This provides compile-time type safety and runtime validation for your Lambda events.

    If you do not wish to type your event, you can select Any for your eventSource, which will result in an any type for the event parameter.

    The generator automatically configures a bundle target which uses Rolldown to create a deployment package:

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

    Rolldown configuration can be found in rolldown.config.ts, with an entry per bundle to generate. Rolldown manages creating multiple bundles in parallel if defined.

    This generator creates CDK or Terraform infrastructure as code based on your selected iacProvider. You can use this to deploy your function.

    This generator creates a CDK construct for deploying your function in the common/constructs folder. You can use this in a CDK application:

    import { MyProjectMyFunction } from ':my-scope/common-constructs';
    export class ExampleStack extends Stack {
    constructor(scope: Construct, id: string) {
    // Add the function to your stack
    const fn = new MyProjectMyFunction(this, 'MyFunction');
    }
    }

    This sets up:

    1. AWS Lambda function
    2. CloudWatch log group
    3. X-Ray tracing configuration
    4. CloudWatch metrics namespace

    This function can then be used as a target for any lambda event source:

    The example below demonstrates the CDK code for invoking your lambda function on a schedule using 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) {
    // Add the function to your stack
    const fn = new MyProjectMyFunction(this, 'MyFunction');
    // Add the function to an EventBridge scheduled rule
    const eventRule = new Rule(this, 'MyFunctionScheduleRule', {
    schedule: Schedule.cron({ minute: '15' }),
    targets: [new LambdaFunction(fn)],
    });
    }
    }