

# TypeScript による Lambda 関数の作成
<a name="lambda-typescript"></a>

Node.js ランタイムを使用すると、TypeScript コードを AWS Lambda で実行できます。Node.js は TypeScript コードをネイティブに実行しないため、最初に TypeScript から JavaScript へのコード変換 (トランスパイル) を行う必要があります。次に、JavaScript ファイルを使用して、この関数コードを Lambda にデプロイします。このコードは、ユーザーが管理する AWS Identity and Access Management (IAM) ロールの認証情報を使用することで、AWS SDK for JavaScript を含む環境内で実行できます。Node.js ランタイムに含まれている SDK バージョンの詳細については、「」を参照してください[ランタイムに含まれる SDK バージョン](lambda-nodejs.md#nodejs-sdk-included)。

Lambda は、以下の Node.js ランタイムをサポートしています。


| 名前 | 識別子 | オペレーティングシステム | 廃止日 | 関数の作成をブロックする | 関数の更新をブロックする | 
| --- | --- | --- | --- | --- | --- | 
|  Node.js 24  |  `nodejs24.x`  |  Amazon Linux 2023  |   2028 年 4 月 30 日   |   2028 年 6 月 1 日   |   2028 年 7 月 1 日   | 
|  Node.js 22  |  `nodejs22.x`  |  Amazon Linux 2023  |   2027 年 4 月 30 日   |   2027 年 6 月 1 日   |   2027 年 7 月 1 日   | 
|  Node.js 20  |  `nodejs20.x`  |  Amazon Linux 2023  |   2026 年 4 月 30 日   |   2026 年 8 月 31 日   |   2026 年 9 月 30 日   | 

**Topics**
+ [TypeScript 開発環境のセットアップ](#typescript-dev)
+ [Lambda のタイプ定義](#typescript-type-definitions)
+ [TypeScript の Lambda 関数ハンドラーの定義](typescript-handler.md)
+ [.zip ファイルアーカイブを使用して、トランスパイルされた TypeScript コードを Lambda にデプロイする](typescript-package.md)
+ [コンテナイメージを使用して、トランスパイルされた TypeScript コードを Lambda にデプロイする](typescript-image.md)
+ [Lambda コンテキストオブジェクトを使用して TypeScript 関数の情報を取得する](typescript-context.md)
+ [TypeScript Lambda 関数のログ記録とモニタリング](typescript-logging.md)
+ [AWS Lambda での TypeScript コードのトレース](typescript-tracing.md)

## TypeScript 開発環境のセットアップ
<a name="typescript-dev"></a>

TypeScript 関数のコードを記述するには、ローカルの統合開発環境 (IDE) またはテキストエディタを使用します。Lambda コンソールでは TypeScript コードを作成できません。

[esbuild](https://esbuild.github.io/) または Microsoft の TypeScript コンパイラ (`tsc`) を使用して、TypeScript コードを JavaScript にトランスパイルできます。[AWS Serverless Application Model (AWS SAM)](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html) と [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) はどちらも esbuild を使用します。

esbuild を使用する際は、以下を考慮してください。
+ [TypeScript に関する注意事項](https://esbuild.github.io/content-types/#typescript-caveats)がいくつか存在します。
+ TypeScript のトランスパイルには、使用する予定の Node.js ランタイムに適合する設定を行う必要があります。詳細については、esbuild ドキュメントの「[Target](https://esbuild.github.io/api/#target)」(ターゲット) を参照してください。Lambda でサポートされている特定の Node.js バージョンをターゲットにする場合の、**tsconfig.json** ファイルの例については、[TypeScript GitHub リポジトリ](https://github.com/tsconfig/bases/blob/main/bases/node14.json)を参照してください。
+ esbuild では、型チェックは行われません。型をチェックする場合は、`tsc` コンパイラを使用します。次の例に示すように、`tsc -noEmit` を実行するか、**tsconfig.json** ファイルに `"noEmit"` パラメータを追加します。これを設定することで、`tsc` は JavaScript ファイルを出力しなくなります。型のチェックが終了したら、esbuild を使用して TypeScript ファイルを JavaScript に変換します。

**Example tsconfig.json**  

```
 {
  "compilerOptions": {
    "target": "es2020",
    "strict": true,
    "preserveConstEnums": true,
    "noEmit": true,
    "sourceMap": false,
    "module":"commonjs",
    "moduleResolution":"node",
    "esModuleInterop": true, 
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true, 
    "isolatedModules": true, 
  },
  "exclude": ["node_modules", "**/*.test.ts"]
}
```

## Lambda のタイプ定義
<a name="typescript-type-definitions"></a>

[@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) パッケージには、Lambda 関数のタイプ定義が用意されています。関数が次のいずれかを使用する場合、このパッケージをインストールします。
+ 一般的な AWS イベントソースには次のようなものがあります。
  + `APIGatewayProxyEvent`: [Amazon API Gateway での Lambda プロキシ統合](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html)用 
  + `SNSEvent`: [Amazon Simple Notification Service 通知](with-sns.md)用
  + `SQSEvent`: [Amazon Simple Queue Service メッセージ](with-sqs.md)用
  + `S3Event`: [S3 トリガーイベント](with-s3.md)用
  + `DynamoDBStreamEvent`: [Amazon DynamoDB Streams](with-ddb.md) 用
+ Lambda の[コンテキスト](typescript-context.md)オブジェクト
+ [コールバック](typescript-handler.md#typescript-handler-callback)ハンドラーパターン

Lambda タイプ定義を関数に追加するには、開発の依存関係として `@types/aws-lambda` をインストールします。

```
npm install -D @types/aws-lambda
```

次に、`aws-lambda` からタイプをインポートします。

```
import { Context, S3Event, APIGatewayProxyEvent } from 'aws-lambda';

export const handler = async (event: S3Event, context: Context) => {
    // Function code
};
```

`import ... from 'aws-lambda'` ステートメントはタイプ定義をインポートします。`aws-lambda` npm パッケージはインポートされません。これは関連性のないサードパーティーのツールです。詳細については、「DefinitelyTyped GitHub リポジトリ」の「[aws-lambda](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/aws-lambda)」を参照してください。

**注記**  
独自のカスタムタイプ定義を使用する場合、[@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) は必要ありません。イベントオブジェクトの独自のタイプを定義する関数の例については、「[TypeScript Lambda 関数コードの例](typescript-handler.md#typescript-example-code)」を参照してください。

# TypeScript の Lambda 関数ハンドラーの定義
<a name="typescript-handler"></a>

Lambda 関数*ハンドラー*は、イベントを処理する関数コード内のメソッドです。関数が呼び出されると、Lambda はハンドラーメソッドを実行します。関数は、ハンドラーが応答を返すか、終了するか、タイムアウトするまで実行されます。

このページでは、プロジェクトのセットアップオプション、命名規則、ベストプラクティスなど、TypeScript で Lambda 関数ハンドラーを使用する方法について説明します。このページには、注文に関する情報を取得し、テキストファイル受信を生成し、このファイルを Amazon Simple Storage Service (Amazon S3) バケットに配置する TypeScript Lambda 関数の例も含まれています。関数を書き込んだ後にデプロイする方法については、「[.zip ファイルアーカイブを使用して、トランスパイルされた TypeScript コードを Lambda にデプロイする](typescript-package.md)」または「[コンテナイメージを使用して、トランスパイルされた TypeScript コードを Lambda にデプロイする](typescript-image.md)」を参照してください。

**Topics**
+ [TypeScript プロジェクトのセットアップ](#typescript-handler-setup)
+ [TypeScript Lambda 関数コードの例](#typescript-example-code)
+ [CommonJS および ES モジュール](#typescript-commonjs-es-modules)
+ [Node.js の初期化](#typescript-initialization)
+ [ハンドラーの命名規則](#typescript-handler-naming)
+ [入力イベントオブジェクトの定義とアクセス](#typescript-example-input)
+ [TypeScript 関数の有効なハンドラーパターン](#typescript-handler-signatures)
+ [ハンドラーでの SDK for JavaScript v3 の使用](#typescript-example-sdk-usage)
+ [環境変数にアクセスする](#typescript-example-envvars)
+ [グローバルな状態を使用する](#typescript-handler-state)
+ [TypeScript Lambda 関数のコードのベストプラクティス](#typescript-best-practices)

## TypeScript プロジェクトのセットアップ
<a name="typescript-handler-setup"></a>

TypeScript 関数のコードを記述するには、ローカルの統合開発環境 (IDE) またはテキストエディタを使用します。Lambda コンソールでは TypeScript コードを作成できません。

TypeScript Lambda プロジェクトを初期化する方法は複数あります。例えば、`npm` を使用してプロジェクト、[AWS SAM アプリケーション](typescript-package.md#aws-sam-ts)、[AWS CDK アプリケーション](typescript-package.md#aws-cdk-ts)などを作成できます。`npm` を使用してプロジェクトを作成するには:

```
npm init
```

関数コードは `.ts` ファイル内にあり、ビルド時に JavaScript ファイルにトランスパイルします。[esbuild](https://esbuild.github.io/) または Microsoft の TypeScript コンパイラ (`tsc`) を使用して、TypeScript コードを JavaScript にトランスパイルできます。esbuild を使用するには、開発の依存関係として追加します。

```
npm install -D esbuild
```

一般的な TypeScript Lambda 関数プロジェクトは、次の一般的な構造に従います。

```
/project-root
  ├── index.ts - Contains main handler
  ├── dist/ - Contains compiled JavaScript
  ├── package.json - Project metadata and dependencies
  ├── package-lock.json - Dependency lock file
  ├── tsconfig.json - TypeScript configuration
  └── node_modules/ - Installed dependencies
```

## TypeScript Lambda 関数コードの例
<a name="typescript-example-code"></a>

以下の Lambda 関数コードの例では、注文に関する情報を取得し、テキストファイル受信を生成し、このファイルを Amazon S3 バケットに配置します。この例では、カスタムイベントタイプ (`OrderEvent`) を定義します。AWS イベントソースのタイプ定義をインポートする方法については、「[Lambda のタイプ定義](lambda-typescript.md#typescript-type-definitions)」を参照してください。

**注記**  
この例では、ES モジュールハンドラーを使用します。Lambda は、ES モジュールと CommonJS ハンドラーの両方をサポートしています。詳細については、「[CommonJS および ES モジュール](nodejs-handler.md#nodejs-commonjs-es-modules)」を参照してください。

**Example index.ts Lambda 関数**  

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

// Initialize the S3 client outside the handler for reuse
const s3Client = new S3Client();

// Define the shape of the input event
type OrderEvent = {
    order_id: string;
    amount: number;
    item: string;
}

/**
 * Lambda handler for processing orders and storing receipts in S3.
 */
export const handler = async (event: OrderEvent): Promise<string> => {
    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 instanceof Error ? error.message : 'Unknown error'}`);
        throw error;
    }
};

/**
 * Helper function to upload receipt to S3
 */
async function uploadReceiptToS3(bucketName: string, key: string, receiptContent: string): Promise<void> {
    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 instanceof Error ? error.message : 'Unknown error'}`);
    }
}
```

この `index.ts` ファイルには以下のコードのセクションが含まれます:
+ `import` ブロック: このブロックを使用して、[AWS SDK クライアント](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/the-request-object.html)などの Lambda 関数に必要なライブラリを含めます。
+ `const s3Client` 宣言: ハンドラー関数の外部で [Amazon S3 クライアント](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/)を初期化します。これにより、Lambda は[初期化フェーズ](lambda-runtime-environment.md#runtimes-lifecycle-ib)中にこのコードを実行し、クライアントは[複数の呼び出しで再利用](lambda-runtime-environment.md#execution-environment-reuse)できるように保持されます。
+ `type OrderEvent`: 予想される入力イベントの構造を定義します。
+ `export const handler`: Lambda が呼び出すメインハンドラー関数です。関数をデプロイするときは、[ハンドラー](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler)プロパティに `index.handler` を指定します。`Handler` プロパティの値は、エクスポートされたハンドラーメソッドのファイル名と名前で、ドットで区切られます。
+ `uploadReceiptToS3` 関数: これは、メインハンドラー関数によって参照されるヘルパー関数です。

この関数が正しく機能するには、[実行ロール](lambda-intro-execution-role.md)で `s3:PutObject` アクションを許可する必要があります。また、必ず `RECEIPT_BUCKET` 環境変数を定義してください。呼び出しに成功したら、Amazon S3 バケットに受信ファイルが含まれているはずです。

## CommonJS および ES モジュール
<a name="typescript-commonjs-es-modules"></a>

Node.js は CommonJS モジュールと ECMAScript モジュール (ES モジュール) の 2 つのモジュールシステムに対応しています。Lambda では、top-level await をサポートしている ES モジュールを使用することをお勧めします。これにより、[実行環境の初期化](#typescript-initialization)中に非同期タスクを完了できます。

Node.js は `.cjs` ファイル名拡張子を持つファイルを CommonJS モジュールとして扱い、`.mjs` 拡張子は ES モジュールを示します。デフォルトでは、Node.js は `.js` ファイル名拡張子を持つファイルを CommonJS モジュールとして扱います。関数の `package.json` ファイルで `type` を `module` として指定することで、`.js` ファイルを ES モジュールとして扱うように Node.js を設定できます。`NODE_OPTIONS` 環境変数に `—experimental-detect-module` フラグを追加することで、`.js` ファイルを CommonJS として扱うか ES モジュールとして扱うかを自動的に検出するように、Lambda で Node.js を設定できます。詳細については、「[Experimental Node.js features](lambda-nodejs.md#nodejs-experimental-features)」を参照してください。

次の例は、ES モジュールと CommonJS モジュールの両方を使用して記述された関数ハンドラーを示しています。このページの残りの例では、すべて ES モジュールを使用しています。

## Node.js の初期化
<a name="typescript-initialization"></a>

Node.js は、イベントループを使用して効率的な非同期操作をサポートするノンブロッキング I/O モデルを使用します。例えば、Node.js がネットワーク呼び出しを行った場合、関数はネットワークレスポンスをブロックすることなく他のオペレーションを処理し続けます。ネットワークレスポンスを受信すると、コールバックキューに配置されます。キューからのタスクは、現在のタスクが完了すると処理されます。

Lambda では、実行環境の初期化中に開始された非同期タスクが初期化中に完了するように、top-level await を使用することをお勧めします。初期化中に完了しない非同期タスクは通常、最初の関数の呼び出し中に実行されます。これにより、予期しない動作またはエラーが引き起こされる可能性があります。例えば、関数の初期化は、AWS Parameter Store からパラメータを取得するためにネットワーク呼び出しを行う場合があります。初期化中にこのタスクが完了しない場合、呼び出し中に値は null になる可能性があります。初期化と呼び出しの間にも遅延が生じる可能性があり、時間的な制約がある操作でエラーが発生する可能性があります。特に、AWS のサービス呼び出しは時間的制約のあるリクエスト署名に依存する可能性があるため、初期化フェーズ中に呼び出しが完了しない場合、サービス呼び出しは失敗します。初期化中にタスクを完了すると、通常、コールドスタートのパフォーマンスが向上し、プロビジョニングされた同時実行の使用時に最初にパフォーマンスが呼び出されます。詳細情報については、ブログ投稿「[Using Node.js ES modules and top-level await in AWS Lambda](https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda)」を参照してください。

## ハンドラーの命名規則
<a name="typescript-handler-naming"></a>

関数を設定すると、[ハンドラー](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler)設定の値はファイル名とエクスポートしたハンドラーメソッドの名前をドットで区切ったものになります。コンソールで作成された関数のデフォルトと、このガイドの例では、`index.handler` です。これは、`index.js` または `index.mjs` ファイルからエクスポートされた `handler` メソッドを示します。

異なるファイル名または関数ハンドラー名を使用してコンソールで関数を作成する場合は、デフォルトのハンドラー名を編集する必要があります。

**関数ハンドラー名を変更するには (コンソール)**

1. Lambda コンソールの [[関数]](https://console.aws.amazon.com/lambda/home#/functions) ページを開き、関数を選択します。

1. **[コード]** タブを選択します。

1. **[ランタイム設定]** ペインまでスクロールして、**[編集]** を選択します。

1. **[ハンドラー]** には、関数ハンドラーの新しい名前を入力します。

1. **[保存]** を選択します。

## 入力イベントオブジェクトの定義とアクセス
<a name="typescript-example-input"></a>

JSON は Lambda 関数の最も一般的な標準入力形式です。この例では、関数は以下のような入力を想定しています:

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

TypeScript で Lambda 関数を使用する場合、タイプまたはインターフェイスを使用して入力イベントの形状を定義できます。この例では、タイプを使用してイベント構造を定義します。

```
type OrderEvent = {
    order_id: string;
    amount: number;
    item: string;
}
```

タイプまたはインターフェイスを定義した後、ハンドラーの署名で使用して、タイプの安全性を確保します。

```
export const handler = async (event: OrderEvent): Promise<string> => {
```

コンパイル中、TypeScript はイベントオブジェクトに正しいタイプの必須フィールドが含まれていることを検証します。例えば、`event.order_id` を数値または `event.amount` を文字列として使用しようとすると、TypeScript コンパイラはエラーを報告します。

## TypeScript 関数の有効なハンドラーパターン
<a name="typescript-handler-signatures"></a>

[コールバック](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/using-a-callback-function.html)を使用する代わりに、[async/await](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/using-async-await.html) を使用して関数ハンドラーを宣言することをお勧めします。async/await は、非同期コードを記述するための簡潔で読みやすい方法であり、ネストされたコールバックや連鎖する promise を必要としません。async/await を使用すると、非同期かつノンブロッキングでありながら、同期コードのように読み取るコードを記述できます。

このセクションの例では `S3Event` タイプを使用します。ただし、[@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) パッケージで他の AWS イベントタイプを使用することも、独自のイベントタイプを定義することもできます。@types/aws-lambda からタイプを使用するには:

1. @types/aws-lambda パッケージを開発の依存関係として追加します。

   ```
   npm install -D @types/aws-lambda
   ```

1. `Context`、`S3Event`、`Callback` など、必要なタイプをインポートします。

### 非同期関数ハンドラー (推奨)
<a name="typescript-handler-async"></a>

`async` キーワードは関数を非同期としてマークし、`await` キーワードは `Promise` が解決されるまで関数の実行を一時停止します。ハンドラーは次の引数を取ります。
+ `event`: 関数に渡された入力データが含まれます。
+ `context`: 呼び出し、関数、および実行環境に関する情報が含まれます。詳細については、「[Lambda コンテキストオブジェクトを使用して TypeScript 関数の情報を取得する](typescript-context.md)」を参照してください。

async/await パターンの有効な署名は次のとおりです。

```
export const handler = async (event: S3Event): Promise<void> => { };
```

```
export const handler = async (event: S3Event, context: Context): Promise<void> => { };
```

**注記**  
項目の配列を非同期で処理する場合は、必ず `Promise.all` で待機を使用して、すべてのオペレーションが完了していることを確認します。`forEach` などのメソッドは、非同期コールバックが完了するまで待機することはありません。詳細については、Mozilla ドキュメントの「[Array.prototype.forEach()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)」を参照してください。

### 同期関数ハンドラー
<a name="typescript-handler-synchronous"></a>

関数が非同期タスクを実行しない場合は、次のいずれかの関数署名を使用して、同期関数ハンドラーを使用できます。

```
export const handler = (event: S3Event): void => { };
```

```
export const handler = (event: S3Event, context: Context): void => { };
```

### レスポンスストリーミング関数ハンドラー
<a name="typescript-handler-response-streaming"></a>

Lambda は Node.js によるレスポンスストリーミングをサポートしています。レスポンスストリーミング関数ハンドラーは、awslambda.streamifyResponse() デコレータを使用し、イベント、responseStream、コンテキストの 3 つのパラメータを使用します。関数の署名は次のとおりです。

```
export const handler = awslambda.streamifyResponse(async (event: APIGatewayProxyEvent, responseStream: NodeJS.WritableStream, context: Context) => { });
```

詳細については、「Lambda 関数のレスポンスストリーミング」を参照してください。

### コールバックベースの関数ハンドラー
<a name="typescript-handler-callback"></a>

**注記**  
コールバックベースの関数ハンドラーは、Node.js 22 までのみサポートされています。Node.js 24 以降では、非同期タスクは非同期関数ハンドラーを使用して実装する必要があります。

コールバックベースの関数ハンドラーは、イベント、コンテキスト、コールバック引数を使用できます。コールバック引数は、`Error` とレスポンスを想定しており、JSON シリアル化可能である必要があります。

コールバックハンドラーパターンの有効な署名は次のとおりです。

```
export const handler = (event: S3Event, context: Context, callback: Callback<void>): void => { };
```

関数は、[イベントループ](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/)が空になるか、関数がタイムアウトするまで実行を続けます。レスポンスは、すべてのイベントループタスクが完了するまで、呼び出し元に送信されません。関数がタイムアウトした場合は、エラーが返ります。すぐにレスポンスが返るようにランタイムを設定するには、[context.callbackWaitsForEmptyEventLoop](typescript-context.md) を false に設定します。

**Example コールバックを持つ TypeScript 関数**  
次の例では、API Gateway 統合に固有の特殊なコールバックタイプである `APIGatewayProxyCallback` を使用します。ほとんどの AWS イベントソースは、上記の署名に示されている汎用 `Callback` タイプを使用します。  

```
import { Context, APIGatewayProxyCallback, APIGatewayEvent } from 'aws-lambda';

export const lambdaHandler = (event: APIGatewayEvent, context: Context, callback: APIGatewayProxyCallback): void => {
    console.log(`Event: ${JSON.stringify(event, null, 2)}`);
    console.log(`Context: ${JSON.stringify(context, null, 2)}`);
    callback(null, {
        statusCode: 200,
        body: JSON.stringify({
            message: 'hello world',
        }),
    });
};
```

## ハンドラーでの SDK for JavaScript v3 の使用
<a name="typescript-example-sdk-usage"></a>

多くの場合、Lambda 関数を使用して、他の AWS リソースとやり取りしたり、更新したりします。これらのリソースとインターフェイスする最も簡単な方法は、AWS SDK for JavaScript を使用することです。サポートされているすべての Lambda Node.js ランタイムには、[SDK for JavaScript バージョン 3](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/) が含まれています。ただし、デプロイパッケージに必要な AWS SDK クライアントを含めることを強くお勧めします。これにより、将来の Lambda ランタイム更新時の[下位互換性](runtimes-update.md#runtime-update-compatibility)が最大化されます。

SDK 依存関係を関数に追加するには、必要な特定の SDK クライアントに `npm install` コマンドを使用します。サンプルコードでは、[Amazon S3 クライアント](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/)を使用しました。この依存関係を追加するには、`package.json` ファイルが格納されているディレクトリで以下のコマンドを実行します。

```
npm install @aws-sdk/client-s3
```

関数コードで、関数の例で示すように、必要なクライアントとコマンドをインポートします。

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

次に、[Amazon S3 クライアント](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/)を初期化します。

```
const s3Client = new S3Client();
```

この例では、関数を呼び出すたびに Amazon S3 クライアントを初期化する必要がないように、メインハンドラー関数の外で Amazon S3 クライアントを初期化しました。SDK クライアントを初期化したら、それを使用してその AWS サービスの API コールを行うことができます。サンプルコードは、以下のように Amazon S3 [PutObject](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/command/PutObjectCommand/) API アクションを呼び出します。

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

## 環境変数にアクセスする
<a name="typescript-example-envvars"></a>

ハンドラーコードでは、`process.env` を使用して任意の[環境変数](configuration-envvars.md)を参照できます。この例では、以下のコード行を使用して、定義された `RECEIPT_BUCKET` 環境変数を参照します:

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

## グローバルな状態を使用する
<a name="typescript-handler-state"></a>

Lambda は、関数を初めて呼び出す前の[初期化フェーズ](lambda-runtime-environment.md#runtimes-lifecycle-ib)で静的コードを実行します。初期化中に作成されたリソースは呼び出し間でメモリに保持されるため、関数を呼び出すたびにリソースを作成する必要がなくなります。

コード例では、S3 クライアント初期化コードはハンドラーの外にあります。ランタイムは、関数が最初のイベントを処理する前にクライアントを初期化し、クライアントはすべての呼び出しで再利用できます。

## TypeScript Lambda 関数のコードのベストプラクティス
<a name="typescript-best-practices"></a>

Lambda 関数を構築するときは、次のガイドラインに従ってください。
+ **Lambda ハンドラーをコアロジックから分離します。**これにより、関数の単体テストが実行しやすくなります。
+ **関数のデプロイパッケージ内で依存関係を制御します。**AWS Lambda 実行環境には多数のライブラリが含まれています。Node.js および Python ランタイムの場合、ライブラリには AWS SDK が含まれます。最新の機能やセキュリティ更新プログラムを有効にするために、Lambda はこれらのライブラリを定期的に更新します。この更新により、Lambda 関数の動作が微妙に変化する場合があります。関数で使用する依存関係を完全に制御するには、すべての依存関係をデプロイパッケージでパッケージングします。
+ **依存関係の複雑さを最小限に抑えます。**フレームワークを単純化して、[実行環境](lambda-runtime-environment.md)起動時のロードを高速化します。
+ **デプロイパッケージをランタイムに必要な最小限のサイズにします。**これにより、呼び出しに先立ってデプロイパッケージをダウンロードして解凍する所要時間が短縮されます。

**実行環境の再利用を活用して関数のパフォーマンスを向上させます。**関数ハンドラー外で SDK クライアントとデータベース接続を初期化し、静的なアセットを `/tmp` ディレクトリにローカルにキャッシュします。関数の同じインスタンスで処理された後続の呼び出しは、これらのリソースを再利用できます。これにより、関数の実行時間が短縮され、コストが節約されます。

呼び出し間でデータが漏れるのを防ぐため、実行環境を使用してセキュリティ上の懸念があるユーザーデータ、イベント、またはその他の情報を保存しないでください。関数がハンドラー内のメモリに保存できない変更可能な状態に依存している場合は、ユーザーごとに個別の関数または個別のバージョンの関数を作成することを検討してください。

**keep-alive ディレクティブを使用して永続的な接続を維持します。**Lambda は、時間の経過とともにアイドル状態の接続を消去します。関数を呼び出すときにアイドル状態の接続を再利用しようとすると、接続エラーが発生します。永続的な接続を維持するには、ランタイムに関連付けられている keep-alive ディレクティブを使用します。例については、「[Node.js で Keep-alive を使用して接続を再利用する](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html)」を参照してください。

**[環境変数](configuration-envvars.md)を使用して、オペレーショナルパラメータを関数に渡します。**たとえば、Amazon S3 バケットに書き込む場合、書き込み先のバケット名はハードコーディングせずに、環境変数として設定します。

Lambda 関数では、**再帰呼び出しを使用しないでください**。関数が自身を呼び出すこともあれば、新たに開始されたプロセスで関数が再度呼び出される可能性もあります。これを行うと意図しないボリュームで関数が呼び出され、料金が急増する可能性があります。意図しない呼び出しがいくつも見つかった場合は、すぐに関数の予約済同時実行数を `0` に設定して、コードを更新している間のすべての関数の呼び出しをスロットリングします。

Lambda 関数コードで**文書化されていない非公開の API を使用しないでください**。AWS Lambda マネージドランタイムでは、Lambda が Lambda の内部 API にセキュリティと機能面の更新を定期的に適用します。これらの内部 API 更新には後方互換性がないことがあり、関数にこれらの非公開 API に対する依存関係がある場合、呼び出しの失敗などの意図しない結果につながります。公開されている API のリストについては、「[API リファレンス](https://docs.aws.amazon.com/lambda/latest/api/welcome.html)」を参照してください。

**冪等性コードを記述します。**関数の記述に冪等性コードを使用すると、重複するイベントが同じ方法で処理されるようになります。コードでは、イベントを適切に検証し、重複するイベントを適切に処理する必要があります。詳細については、「[Lambda 関数を冪等にするにはどうすればよいですか?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/)」を参照してください。

# .zip ファイルアーカイブを使用して、トランスパイルされた TypeScript コードを Lambda にデプロイする
<a name="typescript-package"></a>

TypeScript コードを AWS Lambda にデプロイする前に、JavaScript にトランスパイルする必要があります。このページでは、.zip ファイルアーカイブを使用して TypeScript コードを構築し、Lambda にデプロイする 3 つの方法を説明します。
+ [AWS Serverless Application Model の使用 (AWS SAM)](#aws-sam-ts)
+ [ の使用AWS Cloud Development Kit (AWS CDK)](#aws-cdk-ts)
+ [AWS Command Line Interface (AWS CLI) および esbuild の使用](#aws-cli-ts)

AWS SAM と AWS CDK が、TypeScript 関数のビルドとデプロイを簡素化します。[AWS SAM テンプレート仕様](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification.html)は、サーバーレスアプリケーションを構成する Lambda 関数、API、アクセス許可、設定、およびイベントを記述するためのシンプルで簡潔な構文を提供します。[AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/home.html) を使用すると、プログラミング言語の優れた表現力を活かして、信頼性が高く、スケーラブルで、コスト効率の高いアプリケーションをクラウドで構築できます。AWS CDK は、中級～上級レベルの AWS ユーザーを対象としています。AWS CDK と AWS SAM はどちらも、TypeScript コードの JavaScript へのトランスパイルに esbuild を使用しています。

## AWS SAM を使用して TypeScript コードを Lambda にデプロイする
<a name="aws-sam-ts"></a>

AWS SAM を使用して、Hello World TypeScript サンプルアプリケーションをダウンロード、ビルド、およびデプロイする場合は、以下の手順に従ってください。このアプリケーションは、基本的な API バックエンドを実装し、Amazon API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数が呼び出されます。関数は `hello world` のメッセージを返します。

**注記**  
AWS SAM は esbuild を使用して、TypeScript コードから Node.js Lambda 関数を作成します。esbuild のサポートは、現在パブリックプレビュー中です。パブリックプレビュー中は、esbuild のサポートは、下位互換性のない変更の対象となる場合があります。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM CLI バージョン 1.75 以降](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)
+ Node.js

**AWS SAM サンプルアプリケーションをデプロイする**

1. Hello World TypeScript テンプレートを使用して、アプリケーションを初期化します。

   ```
   sam init --app-template hello-world-typescript --name sam-app --package-type Zip --runtime nodejs24.x
   ```

1. (オプション) サンプルアプリケーションには、コードの linting 用の [ESLint](https://eslint.org/) やユニットテスト用の [Jest](https://jestjs.io/) など、一般的に使用されるツールの設定が含まれています。lint コマンドとテストコマンドを実行するには、次のコードを使用します。

   ```
   cd sam-app/hello-world
   npm install
   npm run lint
   npm run test
   ```

1. アプリケーションを構築します。

   ```
   cd sam-app
   sam build
   ```

1. アプリケーションをデプロイします。

   ```
   sam deploy --guided
   ```

1. 画面に表示されるプロンプトに従ってください。インタラクティブな形式で提供されるデフォルトオプションを受け入れるには、`Enter` を押して応答します。

1. REST API のエンドポイントが出力に表示されます。ブラウザでエンドポイントを開き、関数をテストします。次のレスポンスが表示されます。

   ```
   {"message":"hello world"}
   ```

1. これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することをお勧めします。

   ```
   sam delete
   ```

## AWS CDK を使用して TypeScript コードを Lambda にデプロイする
<a name="aws-cdk-ts"></a>

AWS CDK を使用して TypeScript サンプルアプリケーションをビルドおよびデプロイする場合は、以下の手順に従ってください。このアプリケーションは、基本的な API バックエンドを実装し、API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数が呼び出されます。関数は `hello world` のメッセージを返します。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS CDK バージョン 2](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_prerequisites)
+ Node.js
+ [Docker](https://www.docker.com/get-started/) または [esbuild](https://esbuild.github.io/) のどちらか

**AWS CDK サンプルアプリケーションをデプロイする**

1. 新しいアプリケーション用のプロジェクトディレクトリを作成します。

   ```
   mkdir hello-world
   cd hello-world
   ```

1. アプリケーションを初期化します。

   ```
   cdk init app --language typescript
   ```

1. 開発環境の依存関係として [@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) パッケージを追加します。このパッケージには Lambda の型定義が含まれています。

   ```
   npm install -D @types/aws-lambda
   ```

1. **lib** ディレクトリを開きます。**hello-world-stack.ts** という名前のファイルが表示されます。このディレクトリに **hello-world.function.ts** と **hello-world.ts** の 2 つの新しいファイルを作成します。

1. **hello-world.function.ts** を開き、次のコードをファイルに追加します。これは Lambda 関数のコードです。
**注記**  
`import` ステートメントは、[@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) から型定義をインポートします。`aws-lambda` NPM パッケージはインポートされません。これは関連性のないサードパーティーのツールです。詳細については、「DefinitelyTyped GitHub リポジトリ」の「[aws-lambda](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/aws-lambda)」を参照してください。

   ```
   import { Context, APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda';
   
   export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => {
       console.log(`Event: ${JSON.stringify(event, null, 2)}`);
       console.log(`Context: ${JSON.stringify(context, null, 2)}`);
       return {
           statusCode: 200,
           body: JSON.stringify({
               message: 'hello world',
           }),
       };
   };
   ```

1. **hello-world.ts** を開き、次のコードをファイルに追加します。これには、Lambda 関数を作成する [NodeJsFunction コンストラクト](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs-readme.html)と、REST API を作成する [LambdaRestApi コンストラクト](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.LambdaRestApi.html)が含まれています。

   ```
   import { Construct } from 'constructs';
   import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
   import { LambdaRestApi } from 'aws-cdk-lib/aws-apigateway';
     
   export class HelloWorld extends Construct {
     constructor(scope: Construct, id: string) {
       super(scope, id);
       const helloFunction = new NodejsFunction(this, 'function');
       new LambdaRestApi(this, 'apigw', {
         handler: helloFunction,
       });
     }
   }
   ```

   `NodejsFunction` コンストラクトでは、デフォルトで次のことを前提としています。
   + 関数ハンドラーは `handler` と呼ばれます。
   + 関数コードを含む .ts ファイル (**hello-world.function.ts**) は、コンストラクトを含む .ts ファイル (**hello-world.ts**) と同じディレクトリに存在します。コンストラクトは、コンストラクトの ID (「hello-world」) と Lambda ハンドラーファイルの名前 (「function」) を使用して、関数コードを検索します。例えば、関数コードが **hello-world.my-function.ts** という名前のファイルに含まれている場合、**hello-world.ts** ファイルは、関数コードを次のようにして参照する必要があります。

     ```
     const helloFunction = new NodejsFunction(this, 'my-function');
     ```

   この動作を変更したり、他の esbuild パラメータを設定したりできます。詳細については、「AWS CDK API リファレンス」の「[Configuring esbuild](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs-readme.html#configuring-esbuild)」(esbuild の設定) を参照してください。

1. **hello-world-stack.ts** を開きます。これは、[AWS CDK スタック](https://docs.aws.amazon.com/cdk/v2/guide/stacks.html)を定義するコードです。このコードを、次のコードで置き換えます。

   ```
   import { Stack, StackProps } from 'aws-cdk-lib';
   import { Construct } from 'constructs';
   import { HelloWorld } from './hello-world';
     
   export class HelloWorldStack extends Stack {
     constructor(scope: Construct, id: string, props?: StackProps) {
       super(scope, id, props);
       new HelloWorld(this, 'hello-world');
     }
   }
   ```

1. `cdk.json` ファイルが含まれる `hello-world` ディレクトリから、アプリケーションをデプロイします。

   ```
   cdk deploy
   ```

1. AWS CDK は、esbuild を使用して Lambda 関数をビルドおよびパッケージ化し、その関数を Lambda ランタイムにデプロイします。REST API のエンドポイントが出力に表示されます。ブラウザでエンドポイントを開き、関数をテストします。次のレスポンスが表示されます。

   ```
   {"message":"hello world"}
   ```

   これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することをお勧めします。

## AWS CLI および esbuild を使用して、TypeScript コードを Lambda にデプロイする
<a name="aws-cli-ts"></a>

次の例は、esbuild および AWS CLI を使用して TypeScript コードをトランスパイルし、Lambda にデプロイする方法を示しています。esbuild は、すべての依存関係を含む 1 つの JavaScript ファイルを生成します。これは、.zip アーカイブに追加する必要がある唯一のファイルです。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ Node.js
+ Lambda 関数の[実行ロール](lambda-intro-execution-role.md)
+ Windows ユーザーの場合は、[7zip](https://www.7-zip.org/download.html) などの zip ファイルユーティリティ。

**サンプル関数をデプロイする**

1. ローカルマシンで、新しい関数のプロジェクトディレクトリを作成します。

1. npm または任意のパッケージマネージャーを使用して、新しい Node.js プロジェクトを作成します。

   ```
   npm init
   ```

1. [@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) および [esbuild](https://esbuild.github.io/) のパッケージを開発環境の依存関係として追加します。`@types/aws-lambda` パッケージには Lambda の型定義が含まれています。

   ```
   npm install -D @types/aws-lambda esbuild
   ```

1. **index.ts** という名前の新しいファイルを作成します。次のコードを新しいファイルに追加します。これは Lambda 関数のコードです。関数は `hello world` のメッセージを返します。関数は、API Gateway リソースを作成しません。
**注記**  
`import` ステートメントは、[@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) から型定義をインポートします。`aws-lambda` NPM パッケージはインポートされません。これは関連性のないサードパーティーのツールです。詳細については、「DefinitelyTyped GitHub リポジトリ」の「[aws-lambda](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/aws-lambda)」を参照してください。

   ```
   import { Context, APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda';
   
   export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => {
     console.log(`Event: ${JSON.stringify(event, null, 2)}`);
     console.log(`Context: ${JSON.stringify(context, null, 2)}`);
     return {
         statusCode: 200,
         body: JSON.stringify({
             message: 'hello world',
         }),
      };
   };
   ```

1. ビルドスクリプトを **package.json** ファイルに追加します。これにより、esbuild が.zip デプロイパッケージを自動的に作成するように設定されます。詳細については、esbuild ドキュメントの「[Build scripts](https://esbuild.github.io/getting-started/#build-scripts)」(ビルドスクリプト) を参照してください。

------
#### [ Linux and MacOS ]

   ```
   "scripts": {
     "prebuild": "rm -rf dist",
     "build": "esbuild index.ts --bundle --minify --sourcemap --platform=node --target=es2020 --outfile=dist/index.js",
     "postbuild": "cd dist && zip -r index.zip index.js*"
   },
   ```

------
#### [ Windows ]

   この例では、`"postbuild"` コマンドは [7zip](https://www.7-zip.org/download.html) ユーティリティを使用して .zip ファイルを作成します。お好みの Windows zip ユーティリティを使用し、必要に応じてコマンドを変更します。

   ```
   "scripts": {
     "prebuild": "del /q dist",
     "build": "esbuild index.ts --bundle --minify --sourcemap --platform=node --target=es2020 --outfile=dist/index.js",
     "postbuild": "cd dist && 7z a -tzip index.zip index.js*"
   },
   ```

------

1. パッケージをビルドします。

   ```
   npm run build
   ```

1. .zip デプロイパッケージを使用して Lambda 関数を作成します。ハイライト表示されたテキストを、[実行ロール](lambda-intro-execution-role.md)の Amazon リソースネーム (ARN) で置き換えます。

   ```
   aws lambda create-function --function-name hello-world --runtime "nodejs24.x" --role arn:aws:iam::123456789012:role/lambda-ex --zip-file "fileb://dist/index.zip" --handler index.handler
   ```

1. [テストイベントを実行して](testing-functions.md)、関数が次のレスポンスを返すことを確認します。API Gateway を使用してこの関数を呼び出す場合は、[REST API を作成および設定してください](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html)。

   ```
   {
     "statusCode": 200,
     "body": "{\"message\":\"hello world\"}"
   }
   ```

# コンテナイメージを使用して、トランスパイルされた TypeScript コードを Lambda にデプロイする
<a name="typescript-image"></a>

TypeScript コードを Node.js [コンテナイメージ](images-create.md)として AWS Lambda 関数にデプロイできます。AWS は、コンテナイメージのビルドに役立つ Node.js の[ベースイメージ](nodejs-image.md#nodejs-image-base)を提供します。これらのベースイメージには、Lambda でイメージを実行するために必要な言語ランタイムおよびその他のコンポーネントがプリロードされています。AWS は、コンテナイメージの構築に役立つ各ベースイメージの Dockerfile を提供します。

コミュニティベースイメージまたはプライベートエンタープライズベースイメージを使用する場合は、ベースイメージに [Node.js ランタイムインターフェイスクライアント (RIC) を追加して](nodejs-image.md#nodejs-image-clients)、Lambda と互換性を持たせる必要があります。

Lambda は、ローカルでテストするためのランタイムインターフェイスエミュレータを提供します。Node.js の AWS ベースイメージには、ランタイムインターフェイスエミュレータが含まれています。Alpine Linux や Debian イメージなどの代替ベースイメージを使用する場合は、[エミュレーターをイメージにビルドする](https://github.com/aws/aws-lambda-runtime-interface-emulator/?tab=readme-ov-file#build-rie-into-your-base-image)こともできますし、[ローカルマシンにインストールする](https://github.com/aws/aws-lambda-runtime-interface-emulator/?tab=readme-ov-file#test-an-image-without-adding-rie-to-the-image)こともできます。

## Node.js ベースイメージを使用して TypeScript 関数コードをビルドおよびパッケージ化する
<a name="base-image-typescript"></a>

### 前提条件
<a name="typescript-image-prerequisites"></a>

このセクションの手順を完了するには、以下が必要です。
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (最小バージョン 25.0.0)
+ Docker [buildx プラグイン](https://github.com/docker/buildx/blob/master/README.md)。
+ Node.js 22.x

### ベースイメージからイメージを作成する
<a name="typescript-image-create"></a>

**AWS ベースイメージから Lambda のイメージを作成するには**

1. ローカルマシンで、新しい関数のプロジェクトディレクトリを作成します。

1. `npm` または任意のパッケージマネージャーを使用して、新しい Node.js プロジェクトを作成します。

   ```
   npm init
   ```

1. [@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) および [esbuild](https://esbuild.github.io/) のパッケージを開発環境の依存関係として追加します。`@types/aws-lambda` パッケージには Lambda の型定義が含まれています。

   ```
   npm install -D @types/aws-lambda esbuild
   ```

1. [ビルドスクリプト](https://esbuild.github.io/getting-started/#build-scripts)を `package.json` ファイルに追加します。

   ```
     "scripts": {
     "build": "esbuild index.ts --bundle --minify --sourcemap --platform=node --target=es2020 --outfile=dist/index.js"
   }
   ```

1. `index.ts` という名前のファイルを作成します。その新しいファイルに次のサンプルコードを追加します。これは Lambda 関数のコードです。関数は `hello world` のメッセージを返します。
**注記**  
`import` ステートメントは、[@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) から型定義をインポートします。`aws-lambda` NPM パッケージはインポートされません。これは関連性のないサードパーティーのツールです。詳細については、「DefinitelyTyped GitHub リポジトリ」の「[aws-lambda](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/aws-lambda)」を参照してください。

   ```
   import { Context, APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda';
   
   export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => {
       console.log(`Event: ${JSON.stringify(event, null, 2)}`);
       console.log(`Context: ${JSON.stringify(context, null, 2)}`);
       return {
           statusCode: 200,
           body: JSON.stringify({
               message: 'hello world',
           }),
       };
   };
   ```

1. 次の設定で新しい Dockerfile を作成します。
   + ベースイメージの URI に `FROM` プロパティを設定します。
   + `CMD` 引数を設定して、Lambda 関数ハンドラを指定します。

   次の Dockerfile の例では、「マルチステージビルド」が使用されます。最初のステップでは、TypeScript コードを JavaScript にトランスパイルします。2 番目のステップでは、JavaScript ファイルと本番環境の依存関係のみを含むコンテナイメージを生成します。

   この例の Dockerfile には [USER 命令](https://docs.docker.com/reference/dockerfile/#user)が含まれていないことに注意してください。コンテナイメージを Lambda にデプロイすると、最小特権のアクセス許可を付与したデフォルトの Linux ユーザーを Lambda が自動的に定義します。これは標準の Docker 動作とは異なります。標準の動作とは、`USER` 命令を指定しなかったときに `root` ユーザーのデフォルトとなる動作のことです。  
**Example Dockerfile**  

   ```
   FROM public.ecr.aws/lambda/nodejs:22 as builder
   WORKDIR /usr/app
   COPY package.json index.ts  ./
   RUN npm install
   RUN npm run build
       
   FROM public.ecr.aws/lambda/nodejs:22
   WORKDIR ${LAMBDA_TASK_ROOT}
   COPY --from=builder /usr/app/dist/* ./
   CMD ["index.handler"]
   ```

1. Docker イメージを「[Docker の構築](https://docs.docker.com/engine/reference/commandline/build/)」コマンドで構築します。次の例では、イメージを `docker-image` と名付けて `test` [タグ](https://docs.docker.com/engine/reference/commandline/build/#tag)を付けます。Lambda互換のイメージを作成するには、 `--provenance=false` オプションを使用する必要があります。

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**注記**  
このコマンドは、ビルドマシンのアーキテクチャに関係なく、コンテナが Lambda の実行環境と互換性があることを確認する `--platform linux/amd64` オプションを特定します。ARM64 命令セットアーキテクチャを使用して Lambda 関数を作成する場合は、代わりに `--platform linux/arm64` オプションを使用するようにコマンドを変更してください。

### (オプション) イメージをローカルでテストする
<a name="typescript-image-test"></a>

1. **docker run** コマンドを使用して、Docker イメージを起動します。この例では、`docker-image` はイメージ名、`test` はタグです。

   ```
   docker run --platform linux/amd64 -p 9000:8080 docker-image:test
   ```

   このコマンドはイメージをコンテナとして実行し、`localhost:9000/2015-03-31/functions/function/invocations` でローカルエンドポイントを作成します。
**注記**  
ARM64 命令セットアーキテクチャ用に Docker イメージをビルドした場合は、`--platform linux/amd64` の代わりに `--platform linux/arm64` オプションを使用してください。

1. 新しいターミナルウィンドウから、イベントをローカルエンドポイントにポストします。

------
#### [ Linux/macOS ]

   Linux および macOS では、次の `curl` コマンドを実行します。

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   このコマンドは、空のイベントで関数を呼び出し、応答を返します。サンプル関数コードではなく独自の関数コードを使用している場合は、JSON ペイロードを使用して関数を呼び出すことをお勧めします。例:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

------
#### [ PowerShell ]

   PowerShell で次の `Invoke-WebRequest` コマンドを実行します。

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
   ```

   このコマンドは、空のイベントで関数を呼び出し、応答を返します。サンプル関数コードではなく独自の関数コードを使用している場合は、JSON ペイロードを使用して関数を呼び出すことをお勧めします。例:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
   ```

------

1. コンテナ ID を取得します。

   ```
   docker ps
   ```

1. 「[docker kill](https://docs.docker.com/engine/reference/commandline/kill/)」コマンドを使用してコンテナを停止します。このコマンドでは、`3766c4ab331c` を前のステップのコンテナ ID で置き換えます。

   ```
   docker kill 3766c4ab331c
   ```

### イメージのデプロイ
<a name="typescript-image-deploy"></a>

**Amazon ECR にイメージをアップロードして Lambda 関数を作成するには**

1. 「[get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html)」コマンドを実行して Amazon ECR レジストリに Docker CLI を認証します。
   + `--region` 値を Amazon ECR リポジトリを作成する AWS リージョン に設定します。
   + `111122223333` を AWS アカウント ID に置き換えます。

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. 「[create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html)」コマンドを使用して Amazon ECR にリポジトリを作成します。

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**注記**  
Amazon ECR リポジトリは Lambda 関数と同じ AWS リージョン に配置されている必要があります。

   成功すると、次のようなレスポンスが表示されます。

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. 前のステップの出力から `repositoryUri` をコピーします。

1. 「[docker tag](https://docs.docker.com/engine/reference/commandline/tag/)」コマンドを実行して、最新バージョンとしてローカルイメージを Amazon ECR リポジトリにタグ付けします。このコマンドで:
   + `docker-image:test` は、Docker イメージの名前と[タグ](https://docs.docker.com/engine/reference/commandline/build/#tag)です。これは、`docker build` コマンドに指定したイメージの名前とタグです。
   + `<ECRrepositoryUri>` を、コピーした `repositoryUri` に置き換えます。URI の末尾には必ず `:latest` を含めてください。

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   例:

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. 「[docker push](https://docs.docker.com/engine/reference/commandline/push/)」コマンドを実行して Amazon ECR リポジトリにローカルイメージをデプロイします リポジトリ URI の末尾には必ず `:latest` を含めてください。

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. まだ作成済みでない場合、関数に「[実行ロールの作成](lambda-intro-execution-role.md#permissions-executionrole-api)」を実行してください。次のステップではロールの Amazon リソースネーム (ARN) が必要です。

1. Lambda 関数を作成します。`ImageUri` には、先ほど使用したリポジトリ URI を指定します。URI の末尾には必ず `:latest` を含めてください。

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**注記**  
イメージが Lambda 関数と同じリージョンに配置されていれば、別の AWS アカウントのイメージを使用して関数を作成することができます。詳細については、「[Amazon ECR クロスアカウント許可](images-create.md#configuration-images-xaccount-permissions)」を参照してください。

1. 関数を呼び出します。

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   次のような結果が表示されます。

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. 関数の出力を確認するには、`response.json` ファイルをチェックします。

関数コードを更新するには、イメージを再構築し、新しいイメージを Amazon ECR リポジトリにアップロードしてから、[update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) コマンドを使用してイメージを Lambda 関数にデプロイする必要があります。

Lambda は、イメージタグを特定のイメージダイジェストに解決します。これは、関数のデプロイに使用されたイメージタグを Amazon ECR 内の新しいイメージを指すように変更しても、Lambda は新しいイメージを使用するように自動的に関数を更新しないことを意味します。

新しいイメージを同じ Lambda 関数にデプロイするには、Amazon ECR のイメージタグが同じままであっても、[update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) コマンドを使用する必要があります。次の例では、`--publish` オプションが最新のコンテナイメージを使用して関数の新しいバージョンを作成しています。

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

# Lambda コンテキストオブジェクトを使用して TypeScript 関数の情報を取得する
<a name="typescript-context"></a>

Lambda で関数が実行されると、コンテキストオブジェクトが[ハンドラー](typescript-handler.md)に渡されます。このオブジェクトは、呼び出し、関数、および実行関数に関する情報を示すメソッドおよびプロパティを提供します。

コンテキストオブジェクトのタイプチェックを有効にするには、[@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) パッケージを開発の依存関係として追加し、`Context` タイプをインポートする必要があります。詳細については、「[Lambda のタイプ定義](lambda-typescript.md#typescript-type-definitions)」を参照してください。

**context メソッド**
+ `getRemainingTimeInMillis()` — 実行がタイムアウトするまでの残り時間をミリ秒で返します。

**context プロパティ**
+ `functionName` － Lambda 関数の名前。
+ `functionVersion` － 関数の[バージョン](configuration-versions.md)。
+ `invokedFunctionArn` － 関数を呼び出すために使用される Amazon リソースネーム (ARN)。呼び出し元でバージョン番号またはエイリアスが指定されているかどうかを示します。
+ `memoryLimitInMB` － 関数に割り当てられたメモリの量。
+ `awsRequestId` － 呼び出しリクエストの ID。
+ `logGroupName` － 関数のロググループ。
+ `logStreamName` — 関数インスタンスのログストリーム。
+ `identity` — (モバイルアプリケーション) リクエストを認可した Amazon Cognito ID に関する情報。
  + `cognitoIdentityId` - 認証された Amazon Cognito ID
  + `cognitoIdentityPoolId` — 呼び出しを承認した Amazon Cognito ID プール。
+ `clientContext` —（モバイルアプリケーション）クライアントアプリケーションが Lambda に提供したクライアントコンテキスト。
  + `client.installation_id`
  + `client.app_title`
  + `client.app_version_name`
  + `client.app_version_code`
  + `client.app_package_name`
  + `env.platform_version`
  + `env.platform`
  + `env.make`
  + `env.model`
  + `env.locale`
  + `Custom` - クライアントアプリケーションで設定されたカスタム値。
+ `callbackWaitsForEmptyEventLoop` – デフォルト (`true`) では、コールバックベースの関数ハンドラーを使用する場合、Lambda はコールバックの実行後にイベントループが空になるまで待機してから、関数の呼び出しを終了します。`false` に設定してレスポンスを送信し、イベントループが空になるまで待機するのではなく、コールバックの実行直後に呼び出しを終了します。未完了のイベントは、次の呼び出し中に実行され続けます。Lambda は Node.js 22 以前のランタイムのコールバックベースの関数ハンドラーのみをサポートすることに注意してください。

**Example index.ts ファイル**  
次の例の関数はコンテキスト情報をログに記録して、そのログの場所を返します。  
このコードを Lambda 関数で使用する前に、開発環境の依存関係として [@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) パッケージを追加する必要があります。このパッケージには Lambda の型定義が含まれています。詳細については、「[Lambda のタイプ定義](lambda-typescript.md#typescript-type-definitions)」を参照してください。

```
import { Context } from 'aws-lambda';
export const lambdaHandler = async (event: string, context: Context): Promise<string> => {
  console.log('Remaining time: ', context.getRemainingTimeInMillis());
  console.log('Function name: ', context.functionName);
  return context.logStreamName;
};
```

# TypeScript Lambda 関数のログ記録とモニタリング
<a name="typescript-logging"></a>

AWS Lambda は、Lambda 関数を自動的にモニタリングし、Amazon CloudWatch にログエントリを送信します。Lambda 関数には、関数のインスタンスごとに CloudWatch Logs ロググループとログストリームが用意されています。Lambda のランタイム環境は、各呼び出しの詳細や、関数のコードからのその他の出力をログストリームに送信します。CloudWatch Logs の詳細については、「[Lambda 関数ログを CloudWatch Logs に送信する](monitoring-cloudwatchlogs.md)」を参照してください。

関数コードからログを出力するには、[コンソールオブジェクト](https://nodejs.org/docs/latest-v18.x/api/console.html)のメソッドを使用できます。より詳細なロギングを行うため、`stdout` または `stderr` に書き込みを行う任意のログ記録ライブラリを使用できます。

**Topics**
+ [ログ記録ツールとライブラリの使用](#typescript-tools-libraries)
+ [Powertools for AWS Lambda (TypeScript) と構造化ログ用の AWS SAM の使用](#typescript-logging-sam)
+ [Powertools for AWS Lambda (TypeScript) と構造化ログ用の AWS CDK の使用](#typescript-logging-cdk)
+ [Lambda コンソールでログを表示する](#typescript-logging-console)
+ [CloudWatch コンソールでの ログの表示](#typescript-logging-cwconsole)

## ログ記録ツールとライブラリの使用
<a name="typescript-tools-libraries"></a>

[Powertools for AWS Lambda (TypeScript)](https://docs.aws.amazon.com/powertools/typescript/) は、サーバーレスのベストプラクティスを実装し、開発者の作業速度を向上させるための開発者ツールキットです。[ロガーユーティリティ](https://docs.powertools.aws.dev/lambda/typescript/latest/features/logger/)は、Lambda に最適化されたロガーを提供します。このロガーは、すべての関数の関数コンテキストに関する追加情報を含み、JSON 形式で構成されて出力されます。このユーティリティを使用して次のことができます。
+ Lambda の コンテキスト、コールドスタート、構造から主要キーをキャプチャし、JSON 形式でログ出力する
+ 指示された場合 Lambda 呼び出しイベントをログ記録する (デフォルトでは無効)
+ ログサンプリングにより、特定の割合の呼び出しにのみすべてのログを出力する (デフォルトでは無効)
+ 任意のタイミングで、構造化されたログにキーを追加する
+ カスタムログフォーマッター (Bring Your Own Formatter) を使用して、組織の ログ記録 RFC と互換性のある構造でログを出力する

## Powertools for AWS Lambda (TypeScript) と構造化ログ用の AWS SAM の使用
<a name="typescript-logging-sam"></a>

AWS SAM を使用した統合 [Powertools for AWS Lambda (TypeScript)](https://docs.powertools.aws.dev/lambda-typescript) モジュールを使用して、Hello World TypeScript サンプルアプリケーションをダウンロード、ビルド、およびデプロイする場合は、以下の手順に従ってください。このアプリケーションは基本的な API バックエンドを実装し、Powertools を使用してログ、メトリクス、トレースを生成します。Amazon API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数は呼び出し、Embedded Metric Format を使用してログおよびメトリクスを CloudWatch に送信、トレースを AWS X-Ray に送信します。関数は `hello world` のメッセージを返します。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ Node.js 20 以降
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM「CLI バージョン 1.75 以降](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)」 AWS SAM CLI のバージョンが古い場合は、「[AWS SAM CLI のアップグレード](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade)」を参照してください。

**AWS SAM サンプルアプリケーションをデプロイする**

1. Hello World TypeScript テンプレートを使用して、アプリケーションを初期化します。

   ```
   sam init --app-template hello-world-powertools-typescript --name sam-app --package-type Zip --runtime nodejs24.x
   ```

1. アプリケーションを構築します。

   ```
   cd sam-app && sam build
   ```

1. アプリケーションをデプロイします。

   ```
   sam deploy --guided
   ```

1. 画面に表示されるプロンプトに従ってください。インタラクティブな形式で提供されるデフォルトオプションを受け入れるには、`Enter` を押します。
**注記**  
**[HelloWorldFunction には権限が定義されていない場合がありますが、問題ありませんか？]** には、必ず `y` を入力してください。

1. デプロイされたアプリケーションの URL を取得します。

   ```
   aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
   ```

1. API エンドポイントを呼び出します。

   ```
   curl <URL_FROM_PREVIOUS_STEP>
   ```

   成功すると、次のレスポンスが表示されます。

   ```
   {"message":"hello world"}
   ```

1. 関数のログを取得するには、[sam logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-logs.html) を実行します。詳細については、「*AWS Serverless Application Model デベロッパーガイド*」の「[ログの使用](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html)」を参照してください。

   ```
   sam logs --stack-name sam-app
   ```

   ログ出力は次のようになります。

   ```
   2025/01/31/[$LATEST]4d53e8d279824834a1ccd35511a4949c 2025-08-31T09:33:10.552000 START RequestId: 70693159-7e94-4102-a2af-98a6343fb8fb Version: $LATEST
   2025/01/31/[$LATEST]4d53e8d279824834a1ccd35511a4949c 2025-08-31T09:33:10.594000 2025-08-31T09:33:10.557Z 70693159-7e94-4102-a2af-98a6343fb8fb INFO {"_aws":{"Timestamp":1661938390556,"CloudWatchMetrics":[{"Namespace":"sam-app","Dimensions":[["service"]],"Metrics":[{"Name":"ColdStart","Unit":"Count"}]}]},"service":"helloWorld","ColdStart":1}
   2025/01/31/[$LATEST]4d53e8d279824834a1ccd35511a4949c 2025-08-31T09:33:10.595000 2025-08-31T09:33:10.595Z 70693159-7e94-4102-a2af-98a6343fb8fb INFO {"level":"INFO","message":"This is an INFO log - sending HTTP 200 - hello world response","service":"helloWorld","timestamp":"2025-08-31T09:33:10.594Z"}
   2025/01/31/[$LATEST]4d53e8d279824834a1ccd35511a4949c 2025-08-31T09:33:10.655000 2025-08-31T09:33:10.655Z 70693159-7e94-4102-a2af-98a6343fb8fb INFO {"_aws":{"Timestamp":1661938390655,"CloudWatchMetrics":[{"Namespace":"sam-app","Dimensions":[["service"]],"Metrics":[]}]},"service":"helloWorld"}
   2025/01/31/[$LATEST]4d53e8d279824834a1ccd35511a4949c 2025-08-31T09:33:10.754000 END RequestId: 70693159-7e94-4102-a2af-98a6343fb8fb
   2025/01/31/[$LATEST]4d53e8d279824834a1ccd35511a4949c 2025-08-31T09:33:10.754000 REPORT RequestId: 70693159-7e94-4102-a2af-98a6343fb8fb Duration: 201.55 ms Billed Duration: 202 ms Memory Size: 128 MB Max Memory Used: 66 MB Init Duration: 252.42 ms
   XRAY TraceId: 1-630f2ad5-1de22b6d29a658a466e7ecf5 SegmentId: 567c116658fbf11a Sampled: true
   ```

1. これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することを推奨します。

   ```
   sam delete
   ```

### ログ保持の管理
<a name="typescript-log-retention"></a>

関数を削除しても、ロググループは自動的には削除されません。ログを無期限に保存しないようにするには、ロググループを削除するか、CloudWatch がログを自動的に削除するまでの保持期間を設定します。ログ保持を設定するには、AWS SAM テンプレートに以下を追加します。

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
    # Omitting other properties
  
  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lambda/${HelloWorldFunction}"
      RetentionInDays: 7
```

## Powertools for AWS Lambda (TypeScript) と構造化ログ用の AWS CDK の使用
<a name="typescript-logging-cdk"></a>

AWS CDK を使用した統合 [Powertools for AWS Lambda (TypeScript)](https://docs.powertools.aws.dev/lambda-typescript) モジュールを使用して、Hello World TypeScript サンプルアプリケーションをダウンロード、ビルド、およびデプロイする場合は、以下の手順に従ってください。このアプリケーションは基本的な API バックエンドを実装し、Powertools を使用してログ、メトリクス、トレースを生成します。Amazon API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数は呼び出し、Embedded Metric Format を使用してログおよびメトリクスを CloudWatch に送信、トレースを AWS X-Ray に送信します。関数は `hello world` のメッセージを返します。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ Node.js 20 以降
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS CDK バージョン 2](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_prerequisites)
+ [AWS SAM「CLI バージョン 1.75 以降](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)」 AWS SAM CLI のバージョンが古い場合は、「[AWS SAM CLI のアップグレード](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade)」を参照してください。

**AWS CDK サンプルアプリケーションをデプロイする**

1. 新しいアプリケーション用のプロジェクトディレクトリを作成します。

   ```
   mkdir hello-world
   cd hello-world
   ```

1. アプリケーションを初期化します。

   ```
   cdk init app --language typescript
   ```

1. 開発環境の依存関係として [@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) パッケージを追加します。

   ```
   npm install -D @types/aws-lambda
   ```

1. Powertools [Logger ユーティリティ](https://docs.aws.amazon.com/powertools/typescript/latest/features/logger/)をインストールします。

   ```
   npm install @aws-lambda-powertools/logger
   ```

1. **lib** ディレクトリを開きます。**hello-world-stack.ts** という名前のファイルが表示されます。このディレクトリに **hello-world.function.ts** と **hello-world.ts** の 2 つの新しいファイルを作成します。

1. **hello-world.function.ts** を開き、次のコードをファイルに追加します。これは Lambda 関数のコードです。

   ```
   import { APIGatewayEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
   import { Logger } from '@aws-lambda-powertools/logger';
   const logger = new Logger();
     
   export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => {
     logger.info('This is an INFO log - sending HTTP 200 - hello world response');
     return {
       statusCode: 200,
       body: JSON.stringify({
         message: 'hello world',
       }),
     };
   };
   ```

1. **hello-world.ts** を開き、次のコードをファイルに追加します。これには、Lambda 関数を作成し、Powertools の環境変数を設定し、ログ保持を 1 週間に設定する [NodejsFunction コンストラクト](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs-readme.html)が含まれています。また、REST API を作成する [LambdaRestApi コンストラクト](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.LambdaRestApi.html)も含まれています。

   ```
   import { Construct } from 'constructs';
   import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
   import { LambdaRestApi } from 'aws-cdk-lib/aws-apigateway';
   import { RetentionDays } from 'aws-cdk-lib/aws-logs';
   import { CfnOutput } from 'aws-cdk-lib';
     
   export class HelloWorld extends Construct {
     constructor(scope: Construct, id: string) {
       super(scope, id);
       const helloFunction = new NodejsFunction(this, 'function', {
         environment: {
           Powertools_SERVICE_NAME: 'helloWorld',
           LOG_LEVEL: 'INFO',
         },
         logRetention: RetentionDays.ONE_WEEK,
       });
       const api = new LambdaRestApi(this, 'apigw', {
         handler: helloFunction,
       });
       new CfnOutput(this, 'apiUrl', {
         exportName: 'apiUrl',
         value: api.url,
       });
     }
   }
   ```

1. **hello-world-stack.ts** を開きます。これは、[AWS CDK スタック](https://docs.aws.amazon.com/cdk/v2/guide/stacks.html)を定義するコードです。このコードを、次のコードで置き換えます。

   ```
   import { Stack, StackProps } from 'aws-cdk-lib';
   import { Construct } from 'constructs';
   import { HelloWorld } from './hello-world';
       
   export class HelloWorldStack extends Stack {
     constructor(scope: Construct, id: string, props?: StackProps) {
       super(scope, id, props);
       new HelloWorld(this, 'hello-world');
     }
   }
   ```

1. プロジェクトディレクトリに戻ります。

   ```
   cd hello-world
   ```

1. アプリケーションをデプロイします。

   ```
   cdk deploy
   ```

1. デプロイされたアプリケーションの URL を取得します。

   ```
   aws cloudformation describe-stacks --stack-name HelloWorldStack --query 'Stacks[0].Outputs[?ExportName==`apiUrl`].OutputValue' --output text
   ```

1. API エンドポイントを呼び出します。

   ```
   curl <URL_FROM_PREVIOUS_STEP>
   ```

   成功すると、次のレスポンスが表示されます。

   ```
   {"message":"hello world"}
   ```

1. 関数のログを取得するには、[sam logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-logs.html) を実行します。詳細については、「*AWS Serverless Application Model デベロッパーガイド*」の「[ログの使用](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html)」を参照してください。

   ```
   sam logs --stack-name HelloWorldStack
   ```

   ログ出力は次のようになります。

   ```
   2025/01/31/[$LATEST]2ca67f180dcd4d3e88b5d68576740c8e 2025-08-31T14:48:37.047000 START RequestId: 19ad1007-ff67-40ce-9afe-0af0a9eb512c Version: $LATEST
   2025/01/31/[$LATEST]2ca67f180dcd4d3e88b5d68576740c8e 2025-08-31T14:48:37.050000 {
   "level": "INFO",
   "message": "This is an INFO log - sending HTTP 200 - hello world response",
   "service": "helloWorld",
   "timestamp": "2025-08-31T14:48:37.048Z",
   "xray_trace_id": "1-630f74c4-2b080cf77680a04f2362bcf2"
   }
   2025/01/31/[$LATEST]2ca67f180dcd4d3e88b5d68576740c8e 2025-08-31T14:48:37.082000 END RequestId: 19ad1007-ff67-40ce-9afe-0af0a9eb512c
   2025/01/31/[$LATEST]2ca67f180dcd4d3e88b5d68576740c8e 2025-08-31T14:48:37.082000 REPORT RequestId: 19ad1007-ff67-40ce-9afe-0af0a9eb512c Duration: 34.60 ms Billed Duration: 35 ms Memory Size: 128 MB Max Memory Used: 57 MB Init Duration: 173.48 ms
   ```

1. これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することを推奨します。

   ```
   cdk destroy
   ```

## Lambda コンソールでログを表示する
<a name="typescript-logging-console"></a>

Lambda コンソールを使用して、Lambda 関数を呼び出した後のログ出力を表示できます。

組み込み **Code** エディタからコードがテスト可能である場合、**[実行結果]** でログを確認できます。コンソールのテスト機能を使用して関数を呼び出すと、**[詳細]** セクションで **[ログ出力]** を確認できます。

## CloudWatch コンソールでの ログの表示
<a name="typescript-logging-cwconsole"></a>

Amazon CloudWatch コンソールを使用して、すべての Lambda 関数呼び出しのログを表示できます。

**CloudWatch コンソールでログを表示するには**

1. CloudWatch コンソールの [[Log groups (ロググループ)] ページ](https://console.aws.amazon.com/cloudwatch/home?#logs:)を開きます。

1. 機能のロググループを選択します( **/aws/lambda/*関数名***)

1. ログストリームを選択します

各ログストリームは、[関数のインスタンス](lambda-runtime-environment.md)に相当します。ログストリームは、Lambda 関数を更新したとき、および同時呼び出しを処理するために追加のインスタンスが作成されたときに表示されます。特定の呼び出しのログを検索するために、AWS X-Ray を使って関数をインストルメント化することをお勧めします。　 X-Ray は、リクエストとログストリームの詳細をトレースに記録します。

# AWS Lambda での TypeScript コードのトレース
<a name="typescript-tracing"></a>

Lambda アプリケーションのトレース、デバッグ、最適化を行うために、Lambda は AWS X-Ray と統合されています。X-Ray を使用すると、Lambda 関数や他の AWS のサービスが含まれるアプリケーション内で、リソースを横断するリクエストをトレースできます。

トレーシングデータを X-Ray に送信するには、以下に表示された 3 つの SDK ライブラリのいずれかを使用できます。
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel) – 安全で本番環境に対応し、AWS でサポートされている OpenTelemetry (OTel) SDK のディストリビューション。
+ [AWS X-Ray SDK for Node.js](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs.html) – トレースデータを生成して X-Ray に送信するための SDK。
+ [Powertools for AWS Lambda (TypeScript)](https://docs.aws.amazon.com/powertools/typescript/latest/) – サーバーレスのベストプラクティスを実装し、開発者の作業速度を向上させるための開発者ツールキット。

各 SDK は、テレメトリデータを X-Ray サービスに送信する方法を提供します。続いて、X-Ray を使用してアプリケーションのパフォーマンスメトリクスの表示やフィルタリングを行い、インサイトを取得することで、問題点や最適化の機会を特定できます。

**重要**  
X-Ray および Powertools for AWS Lambda SDK は、AWS が提供する、密接に統合された計測ソリューションの一部です。ADOT Lambda レイヤーは、一般的により多くのデータを収集するトレーシング計測の業界標準の一部ですが、すべてのユースケースに適しているわけではありません。これらのソリューションのいずれかを使用して、X-Ray でエンドツーエンドのトレーシングを実装することができます。選択方法の詳細については、「[Choosing between the AWS Distro for Open Telemetry and X-Ray SDKs](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing)」( Distro for Open Telemetry または X-Ray SDK の選択) を参照してください。

**Topics**
+ [トレース用の Powertools for AWS Lambda (TypeScript) と AWS SAM の使用](#typescript-tracing-sam)
+ [Powertools for AWS Lambda (TypeScript) およびトレース用の AWS CDK の使用](#typescript-tracing-cdk)
+ [X-Ray トレースの解釈](#typescript-tracing-interpretation)

## トレース用の Powertools for AWS Lambda (TypeScript) と AWS SAM の使用
<a name="typescript-tracing-sam"></a>

AWS SAM を使用した統合 [Powertools for AWS Lambda (TypeScript)](https://docs.powertools.aws.dev/lambda-typescript) モジュールを使用して、Hello World TypeScript サンプルアプリケーションをダウンロード、ビルド、およびデプロイする場合は、以下の手順に従ってください。このアプリケーションは基本的な API バックエンドを実装し、Powertools を使用してログ、メトリクス、トレースを生成します。Amazon API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数は呼び出し、Embedded Metric Format を使用してログおよびメトリクスを CloudWatch に送信、トレースを AWS X-Ray に送信します。関数は `hello world` のメッセージを返します。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ Node.js
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM「CLI バージョン 1.75 以降](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)」 AWS SAM CLI のバージョンが古い場合は、「[AWS SAM CLI のアップグレード](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade)」を参照してください。

**AWS SAM サンプルアプリケーションをデプロイする**

1. Hello World TypeScript テンプレートを使用して、アプリケーションを初期化します。

   ```
   sam init --app-template hello-world-powertools-typescript --name sam-app --package-type Zip --runtime nodejs24.x --no-tracing
   ```

1. アプリケーションを構築します。

   ```
   cd sam-app && sam build
   ```

1. アプリケーションをデプロイします。

   ```
   sam deploy --guided
   ```

1. 画面に表示されるプロンプトに従ってください。インタラクティブな形式で提供されるデフォルトオプションを受け入れるには、`Enter` を押します。
**注記**  
**[HelloWorldFunction には権限が定義されていない場合がありますが、問題ありませんか？]** には、必ず `y` を入力してください。

1. デプロイされたアプリケーションの URL を取得します。

   ```
   aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
   ```

1. API エンドポイントを呼び出します。

   ```
   curl <URL_FROM_PREVIOUS_STEP>
   ```

   成功すると、次のレスポンスが表示されます。

   ```
   {"message":"hello world"}
   ```

1. 関数のトレースを取得するには、[sam traces](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-traces.html) を実行します。

   ```
   sam traces
   ```

   トレース出力は次のようになります。

   ```
   XRay Event [revision 1] at (2023-01-31T11:29:40.527000) with id (1-11a2222-111a222222cb33de3b95daf9) and duration (0.483s)
     - 0.425s - sam-app/Prod [HTTP: 200]
       - 0.422s - Lambda [HTTP: 200]
     - 0.406s - sam-app-HelloWorldFunction-Xyzv11a1bcde [HTTP: 200]
     - 0.172s - sam-app-HelloWorldFunction-Xyzv11a1bcde
       - 0.179s - Initialization
       - 0.112s - Invocation
         - 0.052s - ## app.lambdaHandler
           - 0.001s - ### MySubSegment
       - 0.059s - Overhead
   ```

1. これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することを推奨します。

   ```
   sam delete
   ```

X-Ray は、アプリケーションへのすべてのリクエストをトレースするわけではありません。X-Ray は、サンプリングアルゴリズムを適用することで効率的なトレースを行うと同時に、すべてのリクエストについての代表的なサンプルを示します。サンプルレートは 1 秒あたり 1 回のリクエストで、追加リクエストの 5％ です。関数の X-Ray サンプルレートを設定することはできません。

## Powertools for AWS Lambda (TypeScript) およびトレース用の AWS CDK の使用
<a name="typescript-tracing-cdk"></a>

AWS CDK を使用した統合 [Powertools for AWS Lambda (TypeScript)](https://docs.powertools.aws.dev/lambda-typescript) モジュールを使用して、Hello World TypeScript サンプルアプリケーションをダウンロード、ビルド、およびデプロイする場合は、以下の手順に従ってください。このアプリケーションは基本的な API バックエンドを実装し、Powertools を使用してログ、メトリクス、トレースを生成します。Amazon API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数は呼び出し、Embedded Metric Format を使用してログおよびメトリクスを CloudWatch に送信、トレースを AWS X-Ray に送信します。関数は `hello world` のメッセージを返します。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ Node.js
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS CDK バージョン 2](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_prerequisites)
+ 「[AWS SAM CLI バージョン 1.75 以降](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)」 AWS SAM CLI のバージョンが古い場合は、「[AWS SAM CLI のアップグレード](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade)」を参照してください。

**AWS Cloud Development Kit (AWS CDK) サンプルアプリケーションをデプロイする**

1. 新しいアプリケーション用のプロジェクトディレクトリを作成します。

   ```
   mkdir hello-world
   cd hello-world
   ```

1. アプリケーションを初期化します。

   ```
   cdk init app --language typescript
   ```

1. 開発環境の依存関係として [@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) パッケージを追加します。

   ```
   npm install -D @types/aws-lambda
   ```

1. Powertools [Tracer ユーティリティ](https://docs.aws.amazon.com/powertools/typescript/latest/features/tracer/)をインストールします。

   ```
   npm install @aws-lambda-powertools/tracer
   ```

1. **lib** ディレクトリを開きます。**hello-world-stack.ts** という名前のファイルが表示されます。このディレクトリに **hello-world.function.ts** と **hello-world.ts** の 2 つの新しいファイルを作成します。

1. **hello-world.function.ts** を開き、次のコードをファイルに追加します。これは Lambda 関数のコードです。

   ```
   import { APIGatewayEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
   import { Tracer } from '@aws-lambda-powertools/tracer';
   const tracer = new Tracer();
   
   export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => {
     // Get facade segment created by Lambda
     const segment = tracer.getSegment();
   
     // Create subsegment for the function and set it as active
     const handlerSegment = segment.addNewSubsegment(`## ${process.env._HANDLER}`);
     tracer.setSegment(handlerSegment);
   
     // Annotate the subsegment with the cold start and serviceName
     tracer.annotateColdStart();
     tracer.addServiceNameAnnotation();
   
     // Add annotation for the awsRequestId
     tracer.putAnnotation('awsRequestId', context.awsRequestId);
     // Create another subsegment and set it as active
     const subsegment = handlerSegment.addNewSubsegment('### MySubSegment');
     tracer.setSegment(subsegment);
     let response: APIGatewayProxyResult = {
       statusCode: 200,
       body: JSON.stringify({
         message: 'hello world',
       }),
     };
     // Close subsegments (the Lambda one is closed automatically)
     subsegment.close(); // (### MySubSegment)
     handlerSegment.close(); // (## index.handler)
   
     // Set the facade segment as active again (the one created by Lambda)
     tracer.setSegment(segment);
     return response;
   };
   ```

1. **hello-world.ts** を開き、次のコードをファイルに追加します。これには、Lambda 関数を作成し、Powertools の環境変数を設定し、ログ保持を 1 週間に設定する [NodejsFunction コンストラクト](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs-readme.html)が含まれています。また、REST API を作成する [LambdaRestApi コンストラクト](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.LambdaRestApi.html)も含まれています。

   ```
   import { Construct } from 'constructs';
   import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
   import { LambdaRestApi } from 'aws-cdk-lib/aws-apigateway';
   import { CfnOutput } from 'aws-cdk-lib';
   import { Tracing } from 'aws-cdk-lib/aws-lambda';
   
   export class HelloWorld extends Construct {
     constructor(scope: Construct, id: string) {
       super(scope, id);
       const helloFunction = new NodejsFunction(this, 'function', {
         environment: {
           POWERTOOLS_SERVICE_NAME: 'helloWorld',
         },
         tracing: Tracing.ACTIVE,
       });
       const api = new LambdaRestApi(this, 'apigw', {
         handler: helloFunction,
       });
       new CfnOutput(this, 'apiUrl', {
         exportName: 'apiUrl',
         value: api.url,
       });
     }
   }
   ```

1. **hello-world-stack.ts** を開きます。これは、[AWS CDK スタック](https://docs.aws.amazon.com/cdk/v2/guide/stacks.html)を定義するコードです。このコードを、次のコードで置き換えます。

   ```
   import { Stack, StackProps } from 'aws-cdk-lib';
   import { Construct } from 'constructs';
   import { HelloWorld } from './hello-world';
     
   export class HelloWorldStack extends Stack {
     constructor(scope: Construct, id: string, props?: StackProps) {
       super(scope, id, props);
       new HelloWorld(this, 'hello-world');
     }
   }
   ```

1. アプリケーションをデプロイします。

   ```
   cd ..
   cdk deploy
   ```

1. デプロイされたアプリケーションの URL を取得します。

   ```
   aws cloudformation describe-stacks --stack-name HelloWorldStack --query 'Stacks[0].Outputs[?ExportName==`apiUrl`].OutputValue' --output text
   ```

1. API エンドポイントを呼び出します。

   ```
   curl <URL_FROM_PREVIOUS_STEP>
   ```

   成功すると、次のレスポンスが表示されます。

   ```
   {"message":"hello world"}
   ```

1. 関数のトレースを取得するには、[sam traces](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-traces.html) を実行します。

   ```
   sam traces
   ```

   トレース出力は次のようになります。

   ```
   XRay Event [revision 1] at (2023-01-31T11:50:06.997000) with id (1-11a2222-111a222222cb33de3b95daf9) and duration (0.449s)
     - 0.350s - HelloWorldStack-helloworldfunction111A2BCD-Xyzv11a1bcde [HTTP: 200]
     - 0.157s - HelloWorldStack-helloworldfunction111A2BCD-Xyzv11a1bcde
       - 0.169s - Initialization
       - 0.058s - Invocation
         - 0.055s - ## index.handler
           - 0.000s - ### MySubSegment
       - 0.099s - Overhead
   ```

1. これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することを推奨します。

   ```
   cdk destroy
   ```

## X-Ray トレースの解釈
<a name="typescript-tracing-interpretation"></a>

アクティブトレースの設定後は、アプリケーションを通じて特定のリクエストの観測が行えるようになります。[X-Ray トレースマップ](https://docs.aws.amazon.com/xray/latest/devguide/xray-console-servicemap.html)には、アプリケーションとそのすべてのコンポーネントに関する情報が表示されます。次の例はで、サンプルアプリケーションのトレースを示しています。

![\[\]](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images/sample-typescript-servicemap.png)
