

# レスポンスストリーミング対応 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();
});
```