🌵

[アップデート検証]APIGW (REST) + ALB統合 + Response Streaming を試してみた

に公開

先日、Amazon API GatewayのREST APIがALBへ直接統合できるようになりました。

https://aws.amazon.com/jp/blogs/compute/build-scalable-rest-apis-using-amazon-api-gateway-private-integration-with-application-load-balancer/

このアップデートはクラスメソッドさんの記事に詳細が記載してあります。
https://dev.classmethod.jp/articles/api-gateway-rest-apis-integration-load-balancer/

これに加え、response streamingに対応したというアップデートがありました。

https://aws.amazon.com/jp/blogs/compute/building-responsive-apis-with-amazon-api-gateway-response-streaming/

これにより、ALB-ECS構成で生成AIなどのresponse streamingをしたいアプリケーションをホストしている場合も、API Gatewayで認可や流量制御の仕組みをつけて公開することができるようになりました。

ふとAPI Gatewayのresponse streamingとALB統合を同時に利用できるのか疑問に思ったので、この2つのアップデートを同時に検証してみました。

結論

  • API Gatewayのresponse streamingとALB統合を同時に利用可能

ドキュメントの記載

ドキュメントを見ると、下記の記載がありALB統合(private integrations)を利用した場合でも問題なく利用できるように見えます。

You can only use response payload streaming for HTTP_PROXY or AWS_PROXY integration types. This includes Lambda proxy integrations and private integrations that use HTTP_PROXY integrations.

日本語訳

レスポンスペイロードストリーミングは、HTTP_PROXYまたはAWS_PROXY統合タイプにのみ使用できます。これには、Lambdaプロキシ統合とHTTP_PROXY統合を使用するプライベート統合が含まれます。

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/response-transfer-mode.html#response-transfer-mode-considerations

少しややこしいのですが、VPC Linkは統合タイプHTTP_PROXYの中にあるConnection TypeVPC_LINKという位置付けになっています。

統合タイプは公式ドキュメントAWS CLIのドキュメントにある通り、HTTP, AWS,MOCK,HTTP_PROXY,AWS_PROXYの5つとなります。

AWS CLIのドキュメントによると、connectionTypeがVPC_LINKのHTTPまたはHTTPプロキシ統合はプライベート統合と呼ばれるようです。

An HTTP or HTTP proxy integration with a connectionType of VPC_LINK is referred to as a private integration

日本語訳

connectionTypeがVPC_LINKのHTTPまたはHTTPプロキシ統合はプライベート統合と呼ばれ

マネジメントコンソールの画面ではドキュメントでいう統合タイプが選択肢として反映されている訳ではないのでドキュメントを読む際には注意が必要そうですね。

参考までに、API統合タイプとマネジメントコンソールでの表示の対応を表にまとめました。

API統合タイプ マネジメントコンソールでの表示
AWS_PROXY Lambda Proxy
HTTP_PROXY HTTP ProxyまたはVPC Link
(プロキシ統合のトグルをオンにした場合はAPI統合タイプHTTP_PROXYとなる)
HTTP HTTP ProxyまたはVPC Link
(プロキシ統合のトグルをオフにした場合はAPI統合タイプHTTPとなる)
AWS AWSのサービス
MOCK Mock

全体のアーキテクチャ

Private ALB→ECS部分はCDKで、API Gateway部分はAWS CLIでデプロイしていきます。
執筆時点(2025年11月)時点でAPI Gateway REST APIのALB統合がCDKに対応していなかったため、CLIでのデプロイとしました。

アーキテクチャのポイント

  • ECS FargateとALBはPrivate Isolated Subnetに配置
  • VPC Link v2: API GatewayとプライベートALBを接続
  • ストリーミング対応: API Gatewayのresponse streaming機能を有効化

下記のリポジトリにデプロイするためのソースコード一式をuploadしています。
手っ取り早く試したい方はこちらもご利用ください。

https://github.com/yuuyeah/apigw-alb-stream

Step1: Private ALB - ECS構成のデプロイ

Private ALBとECSはCDKでデプロイします。ECSはFastAPIによって2つのエンドポイントを実装しています。

  • /health: ヘルスチェックエンドポイント
  • /stream: Bedrockを使用したストリーミングチャットAPI
    • リアルタイムでBedrock Claude Haikuの応答をストリーミング
    • JSONライン形式でデータを返却

ECSのアプリケーションでは、Bedrockのストリーミングレスポンスを処理しています。

@app.post("/stream")
async def stream_response(req: StreamRequest):
    async def generate():
        response = await loop.run_in_executor(
            None,
            partial(
                bedrock_runtime.converse_stream,
                modelId="global.anthropic.claude-haiku-4-5-20251001-v1:0",
                messages=[{"role": "user", "content": [{"text": req.message}]}],
            ),
        )
        
        stream = response.get("stream")
        if stream:
            for event in stream:
                if "contentBlockDelta" in event:
                    delta = event["contentBlockDelta"]["delta"]
                    if "text" in delta:
                        chunk = json.dumps({"data": delta["text"]}, ensure_ascii=False)
                        yield f"{chunk}\n"
    
    return StreamingResponse(
        generate(),
        media_type="text/event-stream",
        headers={"X-Accel-Buffering": "no", "Cache-Control": "no-cache"},
    )

Step2: API Gatewayの作成とALBの紐付け

AWS CDKとAWS CLIにデプロイ方法を分けた理由ですが、2025/11/29時点でAPI Gateway REST APIとALBの統合はCloudFormation・AWS CDKではサポートしていませんでした。そのため、API Gateway部分はAWS CLIによりデプロイしていきます。

注) Response Streaming部分はCDKで対応しています。
https://github.com/aws/aws-cdk/pull/36155

2-1. AWS CLIのバージョン確認とアップグレード

AWS CLIでデプロイする場合、AWS CLIを特定のバージョン以上にアップグレードする必要があります。私が使っていたAWS CLIのVersionは2.30.xだったのですが、put-integrationAPIを実行する際にUnknown optionsエラーが出てデプロイできませんでした。(2.32.x以降の場合はデプロイに成功しました)

古いVersionを使っている方は下記の手順でアップグレードしましょう。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

2-2. API Gatewayセットアップスクリプトの実行

基本はリポジトリに含まれているセットアップスクリプトを実行すればデプロイできるようにしています。

chmod +x scripts/setup-api-gateway.sh
./scripts/setup-api-gateway.sh

1点、注意する点はHTTP_PROXY統合の設定をする際にresponse modeをSTREAMにしており、タイムアウトは従来のAPI Gatewayで上限緩和なしに設定できなかった60秒に設定しています。

aws apigateway put-integration \
  --rest-api-id "$REST_API_ID" \
  --resource-id "$PROXY_RESOURCE_ID" \
  --http-method ANY \
  --type HTTP_PROXY \
  --integration-http-method ANY \
  --uri "http://${ALB_DNS}/{proxy}" \
  --connection-type VPC_LINK \
  --connection-id "$VPC_LINK_ID" \
  --integration-target "$ALB_ARN" \
  --request-parameters '{"integration.request.path.proxy":"method.request.path.proxy"}' \
  --response-transfer-mode STREAM \
  --timeout-in-millis 60000

Step3: 動作確認

ストリーミングAPIを実行すると下記のような出力になり、正常に動作していることを確認できました。

curl -X POST https://xxxxx.execute-api.us-east-1.amazonaws.com/test/stream \
  -H "Content-Type: application/json" \
  -d '{"message": "日本の首都はどこですか?"}' \
  --no-buffer

レスポンスの例

data: こんにちは

data: !

data: 何

data: か

data: お

data: 手伝い

--no-bufferオプションを指定することで、curlがレスポンスをバッファリングせず、リアルタイムで表示されることを確認できます。

マネジメントコンソールでの確認

Streaming Responseの場合であっても、API Gatewayのマネジメントコンソールから動作確認ができます。

必要なパラメーターを入力して実行すると···

実行結果が返ってきました。マネジメントコンソールの画面からテストした場合は全てのResponseが返ってきてから表示されるようです。

まとめ

API GatewayのALB統合とResponse Streamingの2つの新機能により、ECS/Fargateで動作する生成AIアプリケーションを、API Gatewayの豊富な機能を活用しながら公開できるようになりました。

特に、ストリーミングレスポンスをそのまま返却できる点は、ユーザー体験の向上に大きく貢献します。今後、CDKでの対応が進めば、さらに使いやすくなると思います。

サンプルコードは以下のリポジトリで公開していますので、ぜひ試してみてください。

https://github.com/yuuyeah/apigw-alb-stream

参考リンク

アマゾン ウェブ サービス ジャパン (有志)

Discussion