Skip to content

TypeScriptのLambda関数

TypeScript Lambda Function ジェネレータは、既存のTypeScriptプロジェクトにLambda関数を追加する機能を提供します。

このジェネレータはAWS CDKまたはTerraformのインフラストラクチャ設定を含む新しいTypeScript Lambdaハンドラを作成します。生成されたハンドラは、AWS Lambda Powertools for TypeScriptを使用して、ロギング、AWS X-Rayトレーシング、CloudWatchメトリクスなどの観測可能性を実現し、AWS Lambda PowertoolsのParserを使用したイベントの型安全性(オプション)を提供します。

Lambda関数は2つの方法で生成できます:

  1. インストール Nx Console VSCode Plugin まだインストールしていない場合
  2. VSCodeでNxコンソールを開く
  3. クリック Generate (UI) "Common Nx Commands"セクションで
  4. 検索 @aws/nx-plugin - ts#lambda-function
  5. 必須パラメータを入力
    • クリック Generate
    パラメータ デフォルト 説明
    project 必須 string - Lambda関数を追加するプロジェクト
    functionName 必須 string - 追加する関数の名前
    functionPath string - 関数を追加するプロジェクトソースディレクトリ内のオプションのサブディレクトリ
    eventSource string Any Lambda関数に使用するオプションのイベントソーススキーマ
    iacProvider string Inherit 優先するIaCプロバイダー。デフォルトでは、初期選択から継承されます。

    ジェネレータはプロジェクトに以下のファイルを追加します:

    • Directory<project-name>
      • Directorysrc/
        • <lambda-function>.ts 関数の実装

    functionPathオプションが指定された場合、ジェネレータはプロジェクトのソースディレクトリ内の指定パスにハンドラを追加します:

    • Directory<project-name>
      • Directorysrc/
        • Directory<custom-path>/
          • <function-name>.ts 関数の実装

    このジェネレータは選択した iacProvider に基づいてInfrastructure as Codeを生成するため、packages/common に関連するCDKコンストラクトまたはTerraformモジュールを含むプロジェクトを作成します。

    共通のInfrastructure as Codeプロジェクトは以下の構造を持ちます:

    • Directorypackages/common/constructs
      • Directorysrc
        • Directoryapp/ プロジェクト/ジェネレータ固有のインフラストラクチャ用コンストラクト
        • Directorycore/ app 内のコンストラクトで再利用される汎用コンストラクト
        • index.ts app からコンストラクトをエクスポートするエントリーポイント
      • project.json プロジェクトのビルドターゲットと設定

    ジェネレータは選択したiacProviderに基づいて関数をデプロイするためのインフラストラクチャコードを作成します:

    ジェネレータはCDKコンストラクトを作成します。このコンストラクトはpackages/common/constructs/src/app/lambda-functionsディレクトリに配置され、関数のデプロイに使用できます。

    メインの関数実装は<function-name>.tsにあります。以下は実装例です:

    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: 実装を追加
    };
    export const handler = middy()
    .use(captureLambdaHandler(tracer))
    .use(injectLambdaContext(logger))
    .use(logMetrics(metrics))
    .use(parser({ schema: EventBridgeSchema }))
    .handler(myFunction);

    ジェネレータは以下の機能を自動的に設定します:

    1. 拡張Lambda機能のためのMiddyミドルウェアスタック
    2. 観測可能性のためのAWS Lambda Powertools統合
    3. CloudWatchを使ったメトリクス収集
    4. パーサーミドルウェアを使用した型安全性
    5. Rolldownによる最適化されたデプロイパッケージのバンドリング

    AWS Lambda Powertoolsによる観測可能性

    Section titled “AWS Lambda Powertoolsによる観測可能性”

    ジェネレータはMiddyミドルウェアを通じた自動コンテキスト注入付きの構造化ロギングを設定します。

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

    AWS X-RayトレーシングはcaptureLambdaHandlerミドルウェアで自動設定されます。カスタムサブセグメントを追加できます:

    const tracer = new Tracer();
    export const myFunction = async (
    event: z.infer<typeof EventBridgeSchema>,
    ): Promise<void> => {
    // 新しいサブセグメントを作成
    const subsegment = tracer.getSegment()?.addNewSubsegment('custom-operation');
    try {
    // ここにロジックを実装
    } catch (error) {
    subsegment?.addError(error as Error);
    throw error;
    } finally {
    subsegment?.close();
    }
    };
    export const handler = middy()
    .use(captureLambdaHandler(tracer))
    .handler(myFunction);

    CloudWatchメトリクスはlogMetricsミドルウェアでリクエストごとに自動収集されます。カスタムメトリクスを追加できます:

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

    Lambda関数生成時にeventSourceを選択した場合、関数はAWS Lambda Powertoolsのparserミドルウェアで計装されます。例:

    export const myFunction = async (
    event: z.infer<typeof EventBridgeSchema>,
    ): Promise<void> => {
    event.detail // <- IDEのオートコンプリートが効く型安全なアクセス
    };
    export const handler = middy()
    .use(parser({ schema: EventBridgeSchema }))
    .handler(myFunction);

    これにより、コンパイル時の型安全性とランタイムバリデーションが提供されます。

    イベントの型指定を希望しない場合、eventSourceAnyを選択すると、イベントパラメータはany型になります。

    ジェネレーターは自動的に Rolldown を使用する bundle ターゲットを設定します。このターゲットはデプロイメントパッケージの作成に使用されます:

    Terminal window
    pnpm nx bundle <project-name>

    Rolldownの設定はrolldown.config.tsに記述され、生成するバンドルごとにエントリを定義します。Rolldownは定義された複数のバンドルを並行して作成する処理を管理します。

    このジェネレータは選択した iacProvider に基づいてCDKまたはTerraformのインフラストラクチャーコードを生成します。生成されたコードを使用して関数をデプロイできます。

    このジェネレータは common/constructs フォルダに関数をデプロイするためのCDKコンストラクトを作成します。CDKアプリケーションで以下のように使用できます:

    import { MyProjectMyFunction } from ':my-scope/common-constructs';
    export class ExampleStack extends Stack {
    constructor(scope: Construct, id: string) {
    // スタックに関数を追加
    const fn = new MyProjectMyFunction(this, 'MyFunction');
    }
    }

    これにより以下が設定されます:

    1. AWS Lambda関数
    2. CloudWatchロググループ
    3. X-Rayトレーシング設定
    4. CloudWatchメトリクスネームスペース

    この関数は任意のLambdaイベントソースのターゲットとして使用できます:

    以下の例はEventBridgeを使用してスケジュールでLambda関数を起動するCDKコードを示しています:

    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) {
    // スタックに関数を追加
    const fn = new MyProjectMyFunction(this, 'MyFunction');
    // EventBridgeスケジュールルールに関数を追加
    const eventRule = new Rule(this, 'MyFunctionScheduleRule', {
    schedule: Schedule.cron({ minute: '15' }),
    targets: [new LambdaFunction(fn)],
    });
    }
    }