

# Lambda 関数のレスポンスストリーミング
<a name="configuration-response-streaming"></a>

[Lambda 関数 URL](urls-configuration.md) 経由か、[InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html) API (AWS SDK または直接的な API コール経由) を使用することで、Lambda 関数はレスポンスペイロードをクライアントにストリーミングし、ネイティブに返すことができます。Lambda 関数は、[InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html) API を使用して関数を呼び出す [Amazon API Gateway プロキシ統合](https://docs.aws.amazon.com/apigateway/latest/developerguide/response-transfer-mode-lambda.html)を介してレスポンスペイロードをストリーミングすることもできます。レスポンスストリーミングは、最初のバイトまでの時間 (TTFB) のパフォーマンスを向上させることで、レイテンシーの影響を受けやすいアプリケーションに役立ちます。これは、レスポンスの一部が利用可能になったときにクライアントに返送できるためです。さらに、レスポンスストリーミング関数は、バッファされたレスポンスに対する最大 6 MB と比較して、最大 200 MB のペイロードを返すことができます。レスポンスをストリーミングするということは、関数がレスポンス全体をメモリに収める必要がないことも意味します。レスポンスサイズが非常に大きい場合は、関数に設定する必要のあるメモリ量を減らすことができます。

**注記**  
Lambda レスポンスストリーミングは、すべての AWS リージョン ではまだ利用できません。リージョン別の利用可能な機能については、ビルダーセンターの「[リージョン別の AWS 機能](https://builder.aws.com/build/capabilities)」を参照してください。

Lambda が応答をストリーミングする速度は、レスポンスのサイズに応じて異なります。関数のレスポンスでは、最初の 6 MB に対するストリーミングレートに上限が課されません。レスポンスが 6 MB を超える場合、残りのレスポンスには帯域幅上限が適用されます。ストリーミング帯域幅の詳細については、[レスポンスストリーミングの帯域幅制限](#config-rs-bandwidth-cap) を参照してください。

ストリーミングレスポンスにはコストが発生し、呼び出しているクライアントの接続が切断された際、ストリーミングレスポンスは中断または停止されることはありません。お客様は関数の全機能を利用した期間に対して課金されるため、関数のタイムアウトを長く設定する場合はご注意ください。

Lambda は Node.js マネージドランタイムでのレスポンスストリーミングをサポートしています。Python を含むその他の言語の場合、[カスタムランタイム API 統合を備えたカスタムランタイムを使用](runtimes-custom.md#runtimes-custom-response-streaming)してレスポンスをストリーミングするか、[Lambda Web Adapter](https://github.com/awslabs/aws-lambda-web-adapter) を使用できます。

**注記**  
Lambda コンソールで関数をテストするとき、レスポンスは常にバッファリングされた状態で表示されます。

**Topics**
+ [レスポンスストリーミングの帯域幅制限](#config-rs-bandwidth-cap)
+ [VPC とレスポンスストリーミングの互換性](#config-rs-vpc-compatibility)
+ [レスポンスストリーミング対応 Lambda 関数の記述](config-rs-write-functions.md)
+ [Lambda 関数 URL を使用してレスポンスストリーミング対応関数を呼び出す](config-rs-invoke-furls.md)
+ [チュートリアル: 関数 URL を使用してレスポンスストリーミング Lambda 関数を作成する](response-streaming-tutorial.md)

## レスポンスストリーミングの帯域幅制限
<a name="config-rs-bandwidth-cap"></a>

関数のレスポンスペイロードにおける最初の 6 MB には帯域幅上限がありません。この最初のバースト後、Lambda はレスポンスを最大 2 MBps のレートでストリーミングします。関数のレスポンスが 6 MB を超えないならば、この帯域幅制限が適用されることもありません。

**注記**  
帯域幅制限は関数のレスポンスペイロードにのみ適用され、関数によるネットワークアクセスには適用されません。

上限のない帯域幅は、関数の処理速度を含む多くの要素によって異なります。通常、関数のレスポンスにおける最初の 6 MB には 2 MBps より高いレートを期待できます。関数が AWS 外部の宛先にレスポンスをストリーミングする場合、ストリーミングレートは外部インターネット接続の速度にも依存します。

## VPC とレスポンスストリーミングの互換性
<a name="config-rs-vpc-compatibility"></a>

VPC 環境で Lambda 関数を使用する場合は、レスポンスストリーミングに関する重要な考慮事項があります。
+ Lambda 関数 URL は、VPC 環境内でのレスポンスストリーミングをサポートしていません。
+ `InvokeWithResponseStream` API を使用して AWS SDK を介して Lambda 関数を呼び出すことで、VPC 内のレスポンスストリーミングを使用できます。これを使用するには、Lambda 用の適切な VPC エンドポイントを設定する必要があります。
+ VPC 環境の場合、VPC 内のリソースと Lambda サービス間の通信を可能にするには、Lambda 用のインターフェイス VPC エンドポイントを作成する必要があります。

VPC でのレスポンスストリーミングの一般的なアーキテクチャには、次のようなものがあります。

```
Client in VPC -> Interface VPC endpoint for Lambda -> Lambda function -> Response streaming back through the same path
```

# レスポンスストリーミング対応 Lambda 関数の記述
<a name="config-rs-write-functions"></a>

レスポンスストリーミング関数のハンドラー記述は、一般的なハンドラーパターンとは異なります。ストリーミング関数の作成時は、必ず次の事項を確認してください。
+ 関数を `awslambda.streamifyResponse()` デコレーターでラップします。`awslambda` グローバルオブジェクトは、Lambda の Node.js ランタイム環境で提供されます。
+ 確実にすべてのデータ処理を完了させるため、ストリームを正常に終了させます。

## ストリームレスポンスにハンドラー関数を設定する
<a name="config-rs-write-functions-handler"></a>

Lambda が関数のレスポンスをストリーミングする必要があることをランタイムに示すには、関数を `streamifyResponse()` デコレーターでラップする必要があります。これにより、レスポンスをストリーミングするために適切なロジックパスを使用するようランタイムに指示し、関数がレスポンスをストリーミングできるようにします。

`streamifyResponse()` デコレーターは、次のパラメータを受けつける関数を受けつけます。
+ `event` — HTTP メソッド、クエリパラメータ、リクエスト本文など、関数 URL の呼び出しイベントに関する情報を提供します。
+ `responseStream` — 書き込み可能なストリームを提供します。
+ `context` – 呼び出し、関数、実行環境に関する情報を含むメソッドおよびプロパティを提供します。

`responseStream` オブジェクトは「[Node.js `writableStream`](https://nodesource.com/blog/understanding-streams-in-nodejs/)」です。他のこのようなストリームと同様に、`pipeline()` メソッドを使用する必要があります。

**注記**  
`awslambda` グローバルオブジェクトは Lambda の Node.js ランタイムにより自動的に提供され、インポートは不要です。

**Example レスポンスストリーミング対応ハンドラー**  

```
import { pipeline } from 'node:stream/promises';
import { Readable } from 'node:stream';

export const echo = awslambda.streamifyResponse(async (event, responseStream, _context) => {
  // As an example, convert event to a readable stream.
  const requestStream = Readable.from(Buffer.from(JSON.stringify(event)));

  await pipeline(requestStream, responseStream);
});
```

`responseStream` にはストリームに書き込む `write()` メソッドが用意されていますが、「[https://nodejs.org/api/stream.html#streampipelinesource-transforms-destination-callback](https://nodejs.org/api/stream.html#streampipelinesource-transforms-destination-callback)」を可能な限り使用することをお勧めします。`pipeline()` を使用すると、書き込み可能なストリームが読み取り速度の速いストリームによって抑制されることがなくなります。

## ストリームを終了する
<a name="config-rs-write-functions-end"></a>

ハンドラーが戻る前にストリームが適切に終了することを確認してください。`pipeline()` メソッドはこれを自動的に処理します。

他のユースケースでは、`responseStream.end()` メソッドを呼び出してストリームを適切に終了させます。このメソッドは、ストリームにこれ以上データを書き込む必要がないことを通知します。`pipeline()` または `pipe()` でストリームに書き込む場合、このメソッドは不要です。

Node.js 24 以降、ハンドラーが返すか、レスポンスストリームが終了した後、Lambda は未解決の約束が完了するまで待機しなくなりました。関数が追加の非同期オペレーション (タイマーやフェッチなど) に依存している場合、ハンドラーで `await` を行う必要があります。

**Example pipeline() でストリームを終了する例**  

```
import { pipeline } from 'node:stream/promises';

export const handler = awslambda.streamifyResponse(async (event, responseStream, _context) => {
  await pipeline(requestStream, responseStream);
});
```

**Example pipeline() なしでストリームを終了する例**  

```
export const handler = awslambda.streamifyResponse(async (event, responseStream, _context) => {
  responseStream.write("Hello ");
  responseStream.write("world ");
  responseStream.write("from ");
  responseStream.write("Lambda!");
  responseStream.end();
});
```

# Lambda 関数 URL を使用してレスポンスストリーミング対応関数を呼び出す
<a name="config-rs-invoke-furls"></a>

**注記**  
Lambda 関数は、[Amazon API Gateway プロキシ統合](https://docs.aws.amazon.com/apigateway/latest/developerguide/response-transfer-mode-lambda.html)を通じてレスポンスペイロードのストリーミングができるようになりました。

関数 URL の呼び出しモードを変更することで、レスポンスストリーミング対応関数を呼び出すことができます。呼び出しモードは、Lambda が関数を呼び出すために使用する API オペレーションを決定します。利用可能な呼び出しモードは以下のとおりです。
+ `BUFFERED` – これはデフォルトのオプションです。Lambda は `Invoke` API オペレーションを使用して関数を呼び出します。ペイロードが完了すると、呼び出し結果が表示されます。最大ペイロードサイズは 6 MB です。
+ `RESPONSE_STREAM` — ペイロード結果が利用可能になったら、関数がそれをストリーミングできるようにします。Lambda は `InvokeWithResponseStream` API オペレーションを使用して関数を呼び出します。レスポンスペイロードの最大サイズは 200 MB です。

`Invoke` API オペレーションを直接呼び出すことにより、レスポンスストリーミングなしで関数を呼び出すことができます。ただし、呼び出しモードを `BUFFERED` に変更しない限り、Lambda は関数 URL を経由するすべての呼び出しレスポンスペイロードをストリーミングします。

------
#### [ Console ]

**関数 URL の呼び出しモードを設定するには (コンソール)**

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

1. 呼び出しモードを設定する関数の名前を選択します。

1. **[設定]** タブを開き、次に **[関数 URL]** をクリックします。

1. **[編集]** を選択し、次に **[追加設定]** を選択します。

1. **[呼び出しモード]** で目的の呼び出しモードを選択します。

1. **[保存]** をクリックします。

------
#### [ AWS CLI ]

**関数の URL の呼び出しモードを設定するには (AWS CLI)**

```
aws lambda update-function-url-config \
  --function-name my-function \
  --invoke-mode RESPONSE_STREAM
```

------
#### [ CloudFormation ]

**関数の URL の呼び出しモードを設定するには (CloudFormation)**

```
MyFunctionUrl:
  Type: AWS::Lambda::Url
  Properties:
    AuthType: AWS_IAM
    InvokeMode: RESPONSE_STREAM
```

------

関数 URL の設定の詳細については、「[Lambda 関数 URL](urls-configuration.md)」を参照してください。

# チュートリアル: 関数 URL を使用してレスポンスストリーミング Lambda 関数を作成する
<a name="response-streaming-tutorial"></a>

このチュートリアルでは、レスポンスストリームを返す関数 URL エンドポイントを持つ .zip ファイルアーカイブとして定義された Lambda 関数を作成します。関数 URL の設定の詳細については、「[関数 URL](urls-configuration.md)」を参照してください。

## 前提条件
<a name="response-streaming-prepare"></a>

このチュートリアルでは、基本的な Lambda オペレーションと Lambda コンソールについてある程度の知識があることを前提としています。初めての方は、[コンソールで Lambda の関数の作成](getting-started.md#getting-started-create-function) の手順に従って最初の Lambda 関数を作成してください。

以下の手順を完了するには、[AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) が必要です。コマンドと予想される出力は、別々のブロックにリストされます。

```
aws --version
```

次のような出力が表示されます。

```
aws-cli/2.13.27 Python/3.11.6 Linux/4.14.328-248.540.amzn2.x86_64 exe/x86_64.amzn.2
```

コマンドが長い場合、コマンドを複数行に分割するためにエスケープ文字 (`\`) が使用されます。

Linux および macOS では、任意のシェルとパッケージマネージャーを使用します。

**注記**  
Windows では、Lambda でよく使用される一部の Bash CLI コマンド (`zip` など) が、オペレーティングシステムの組み込みターミナルでサポートされていません。Ubuntu および Bash の Windows 統合バージョンを取得するには、[Windows Subsystem for Linux をインストール](https://docs.microsoft.com/en-us/windows/wsl/install-win10)します。このガイドの CLI コマンドの例では、Linux フォーマットを使用しています。Windows CLI を使用している場合、インライン JSON ドキュメントを含むコマンドを再フォーマットする必要があります。

## 実行ロールを作成する
<a name="response-streaming-create-iam-role"></a>

AWS リソースにアクセスするためのアクセス権限を Lambda 関数に付与する[実行ロール](lambda-intro-execution-role.md)を作成します。

**実行ロールを作成するには**

1. AWS Identity and Access Management (IAM) コンソールの [ロールページ](https://console.aws.amazon.com/iam/home#/roles)を開きます。

1. [**ロールの作成**] を選択してください。

1. 次のプロパティでロールを作成します。
   + **[信頼できるエンティティタイプ]** – **[AWS のサービス]**
   + **[ユースケース]** – **[Lambda]**
   + **アクセス許可** - **AWSLambdaBasicExecutionRole**。
   + **[ロール名]** – **response-streaming-role**

**AWSLambdaBasicExecutionRole** ポリシーには、ログを Amazon CloudWatch Logs に書き込むために関数が必要とするアクセス許可が含まれています。ロールを作成した後、Amazon リソースネーム (ARN) を書き留めてください。これは次のステップで必要になります。

## レスポンスストリーミング関数を作成する (AWS CLI)
<a name="response-streaming-tutorial-create-function-cli"></a>

AWS Command Line Interface (AWS CLI) を使用して、関数 URL エンドポイントでレスポンスストリーミング Lambda 関数を作成します。

**レスポンスをストリーミングできる関数を作成するには**

1. 以下のコード例を `index.js` という名前のファイルにコピーします。この関数は、1 秒で区切られた 3 つのレスポンスをストリーミングします。

   ```
   exports.handler = awslambda.streamifyResponse(
   	async (event, responseStream, _context) => {
   		// Metadata is a JSON serializable JS object. Its shape is not defined here.
   		const metadata = {
   		statusCode: 200,
   		headers: {
   			"Content-Type": "application/json",
   			"CustomHeader": "outerspace"
   		}
   		};
   	
   		// Assign to the responseStream parameter to prevent accidental reuse of the non-wrapped stream.
   		responseStream = awslambda.HttpResponseStream.from(responseStream, metadata);
   	
   		responseStream.write("Streaming with Helper \n");
   		await new Promise(r => setTimeout(r, 1000));
   		responseStream.write("Hello 0 \n");
   		await new Promise(r => setTimeout(r, 1000));
   		responseStream.write("Hello 1 \n");
   		await new Promise(r => setTimeout(r, 1000));
   		responseStream.write("Hello 2 \n");
   		await new Promise(r => setTimeout(r, 1000));
   		responseStream.end();
   		await responseStream.finished();
   	}
     );
   ```

1. デプロイパッケージを作成します。

   ```
   zip function.zip index.js
   ```

1. `create-function` コマンドを使用して Lambda 関数を作成します。`--role` の値を、前のステップで書き留めたロールの ARN に置き換えます。このコマンドは、関数のタイムアウトを 10 秒に設定し、関数が 3 つのレスポンスをストリーミングできるようにします。

   ```
   aws lambda create-function \
     --function-name my-streaming-function \
     --runtime nodejs24.x \
     --zip-file fileb://function.zip \
     --handler index.handler \
     --timeout 10 \
     --role arn:aws:iam::123456789012:role/response-streaming-role
   ```

**関数 URL を作成するには**

1. `lambda:InvokeFunctionUrl` および `lambda:InvokeFunction` のアクセス許可を付与するリソースベースのポリシーを関数に追加します。各ステートメントは、個別のコマンドで追加する必要があります。`--principal` の値を AWS アカウント  ID に置き換えます。

   ```
   aws lambda add-permission \
     --function-name my-streaming-function \
     --action lambda:InvokeFunctionUrl \
     --statement-id UrlPolicyInvokeURL \
     --principal 123456789012 \
     --function-url-auth-type AWS_IAM
   ```

   ```
   aws lambda add-permission \
       --function-name my-streaming-function \
       --action lambda:InvokeFunction \
       --statement-id UrlPolicyInvokeFunction \
       --principal 123456789012
   ```

1. `create-function-url-config` コマンドを使用して、関数の URL エンドポイントを作成します。

   ```
   aws lambda create-function-url-config \
     --function-name my-streaming-function \
     --auth-type AWS_IAM \
     --invoke-mode RESPONSE_STREAM
   ```
**注記**  
`--invoke-mode` に関するエラーが発生した場合は、[AWS CLI の新しいバージョン](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)にアップグレードする必要がある場合があります。

## 関数 URL エンドポイントをテストする
<a name="response-streaming-tutorial-test"></a>

関数を呼び出して統合をテストします。関数 URL をブラウザで開くことも、curl を使用することもできます。

```
curl --request GET "https://abcdefghijklm7nop7qrs740abcd.lambda-url.us-east-1.on.aws/" --user "AKIAIOSFODNN7EXAMPLE" --aws-sigv4 "aws:amz:us-east-1:lambda" --no-buffer
```

関数 URL では、認証タイプ `IAM_AUTH` を使用します。つまり、[AWS アクセスキーとシークレットキー](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)の両方でリクエストに署名する必要があります。前のコマンドで、`AKIAIOSFODNN7EXAMPLE` を AWS アクセスキー ID に置き換えます。プロンプトが表示されたら、AWS シークレットキーを入力します。AWS シークレットキーがない場合は、代わりに[一時的な AWS 認証情報](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)を使用できます。

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

```
Streaming with Helper 
Hello 0 
Hello 1
Hello 2
```

## リソースのクリーンアップ
<a name="cleanup"></a>

このチュートリアル用に作成したリソースは、保持しない場合は削除できます。使用しなくなった AWS リソースを削除することで、AWS アカウント アカウントに請求される料金の発生を防ぎます。

**実行ロールを削除する**

1. IAM コンソールの [[ロール]](https://console.aws.amazon.com/iam/home#/roles) ページを開きます。

1. 作成した実行ロールを選択します。

1. **[削除]** を選択します。

1. テキスト入力フィールドにロールの名前を入力し、**[削除]** を選択します。

**Lambda 関数を削除するには**

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

1. 作成した関数を選択します。

1. **[アクション]** で、**[削除]** を選択します。

1. テキスト入力フィールドに **confirm** と入力し、**[Delete]** (削除) を選択します。