Cloud Service
Amazon API Gateway WebSocket APIs
双方向のリアルタイム通信をマネージドで実現。サーバーを常駐させずチャットや通知をLambda等へ繋ぐ、AWS版WebSocketの玄関。
- 1.クライアントとサーバーが繋ぎっぱなしで双方向にやり取りできる窓口。
- 2.接続・切断・メッセージをルートで振り分けLambda等で処理する。
- 3.サーバーへの送信は接続IDを使った逆方向のManagement APIで行う。
解決する課題
- チャットや通知で双方向のリアルタイム通信がしたい
- WebSocketサーバーを自前で常駐運用したくない
- 多数の同時接続を接続管理ごとマネージドに任せたい
主要概念と用語
- 接続(コネクション): クライアントが繋ぎっぱなしにする経路。各接続に一意の接続IDが付く
- ルート: 受信メッセージの内容で処理先を振り分ける仕組み
$connect/$disconnect: 接続開始・切断時に呼ばれる組み込みルート$default: どのルートにも一致しないメッセージを受けるルート- ルート選択式: メッセージのどのフィールドでルートを選ぶかを定義する式
@connectionsManagement API: サーバー側から接続IDを指定してメッセージを送る逆方向API
仕様・制限・クォータ
- フルマネージドで接続を維持し、自動スケールする
- 接続のアイドルタイムアウトや、最大接続継続時間に上限がある
- 一定時間メッセージが無いとアイドルとして切断され得る
- メッセージのペイロードサイズに上限がある(大きいデータはS3+参照が定石)
WebSocketの接続にはアイドルタイムアウトと最大継続時間の上限があります。 クライアント側に再接続ロジックを入れて、切れても復帰できるように設計します。
内部の仕組み
クライアントが接続すると $connect ルートが呼ばれ、ここで認証や接続IDの保存を行います。
以降クライアントが送るメッセージはルート選択式で評価され、一致したルート(無ければ $default)の統合先(Lambda等)へ振り分けられます。
切断時には $disconnect ルートが呼ばれます。
サーバー側からクライアントへ送るのは逆方向で、@connections の Management API に接続IDを指定して POST します。
そのため「誰がどの接続IDか」をDynamoDB等に保存しておくのが基本パターンです。
API Gateway は接続IDを発行しますが、宛先の管理はしてくれません。
$connect で接続IDをDynamoDBに保存し、送信時に引き当てる構成が定番です。
設計パターン / ベストプラクティス
- WebSocket API + Lambda + DynamoDB: 接続をDynamoDBに記録し、送信時に引き当てる
$connectでオーソライザー(Lambda/IAM)を使い接続時に認証する- ファンアウトしたい時は保存済みの接続IDを走査して順に送信する
- 大きいペイロードはS3に置きメッセージには参照を載せる
- クライアントに再接続とバックオフを実装する
運用・監視
- メトリクス:
ConnectCountMessageCountIntegrationErrorClientErrorExecutionError - アクセスログ/実行ログをCloudWatchへ出して接続・切断・ルート選択を追跡
410 Goneが返る送信は切断済みの接続ID。DynamoDB側から削除する- スロットリングはステージ/ルート単位で設定できる
コスト
- メッセージ数と**接続時間(接続分)**で課金される従量制
- 常駐サーバーが不要なため、接続が疎な用途ではコスト効率が良い
- 切断済みの接続IDを掃除し、無駄な送信試行を減らすと運用コストも下がる
セキュリティ
$connect時にLambdaオーソライザー / IAM認証で接続を認証する- 接続後のメッセージにはトークン検証などアプリ側の認可も検討する
- 通信はTLS(wss)。前段にWAFを併用して保護できる
- IAMで
@connectionsManagement API の呼び出し権限を最小化する
関連サービス・比較
同じ API Gateway のプロトコルである REST API(リクエスト/レスポンス型)と、通信モデルが根本的に異なります。
| 観点 | WebSocket API | REST API |
|---|---|---|
| 通信モデル | 双方向・接続維持 | 片方向・都度リクエスト |
| 向く用途 | チャット/通知/実況 | 通常のWeb/モバイルAPI |
| サーバー送信 | 接続IDで逆方向送信 | レスポンスで返すのみ |
| 課金 | 接続時間とメッセージ数 | リクエスト数 |
ハンズオン / CLI例
# WebSocket API を作成(ルート選択式を指定)
aws apigatewayv2 create-api \
--name chat-ws --protocol-type WEBSOCKET \
--route-selection-expression '$request.body.action'
# サーバー側から接続IDを指定してメッセージを送る(逆方向)
aws apigatewaymanagementapi post-to-connection \
--connection-id "$CONN_ID" \
--endpoint-url "https://abcde12345.execute-api.ap-northeast-1.amazonaws.com/prod" \
--data '{"message":"hello"}'
AWS Service
Amazon API Gateway WebSocket APIsを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
アプリ統合
比較で見る軸
クラウド: AWS / カテゴリ: アプリ統合 / 難易度: intermediate
導入後に効く点
接続・切断・メッセージをルートで振り分けLambda等で処理する。
先に潰すリスク
サービス単体ではなく、権限、ネットワーク、監視、課金、バックアップを含めて設計する必要がある。
- クラウド
- AWS
- カテゴリ
- アプリ統合
- 難易度
- intermediate
- 関連資格
- SAA-C03 / DVA-C02 / SAP-C02
- 設計柱
- performance / operational / cost / security
判断チェックリスト
- 自社の用途が「アプリ統合 / performance」に近いか確認する。
- 強みである「クライアントとサーバーが繋ぎっぱなしで双方向にやり取りできる窓口。」が本当に評価軸になるか確認する。
- 注意点の「サービス単体ではなく、権限、ネットワーク、監視、課金、バックアップを含めて設計する必要がある。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。