API Gateway で Websocket 開発(仕組み編)
概要
API Gateway では Websocket 接続もサポートされている事を知りました。
使い勝手を調べたところ、自分のイメージとは(良い意味で)異なっていました。
この記事では、自分の理解を整理するため、特徴的だと感じた仕様をまとめます。
目次
- 用語
- 要点
- 通信プロトコル周り
- サーバー側から API Gateway を介して Websocket クライアントと通信を開始する
- "ルート" 情報で、転送先サーバー側アプリケーションを制御
- クォータ
- 感想
- 参考文献
用語
用語 | 意味 |
---|---|
クライアント | API Gawatey へ Websocket 接続を要求する側 |
サーバー | クライアントのWebsocket 通信に応じて、サービスを提供する側 |
要点
- 通信プロトコル周り
- クライアントと API Gateway 間は
wss
(orws
) プロトコルで通信 - API Gateway と サーバー間は REST APIで通信
- クライアントと API Gateway 間は
- サーバー側から API Gateway を介して Websocket クライアントと通信を開始する
- サーバー側から通信を開始する際、
connection_id
という情報を用いて、通信したいクライアントを識別する -
@connections
コマンドを使用して、サーバー側から通信を開始する-
@connections
コマンドの中で、connection_id
を指定する
-
- サーバー側から通信を開始する際、
- "ルート" 情報で、転送先サーバー側アプリケーションを制御
- Websocket メッセージの内容に応じて、ルートが決まる
- ルート別に、「ルートが選択されたときに実行したいサーバー側アプリケーション」を設定できる
- サーバーレスアプリケーションも設定できる(Lambdaに至っては統合されている)
- これらの設定により、Websocket メッセージを使って、実行したいサーバー側アプリケーションを制御できる
通信プロトコル周り
クライアント と API Gateway 間は wss(or ws) プロトコルにて通信します。
一方、API Gateway とサーバー間は REST API で通信します。
クライアント側では wss
(または ws
)プロトコルでアプリケーションを開発し、 Websocket の機能を享受できます。
一方、サーバー側では、使い慣れ、フレームワークも実績も豊富な REST API でアプリケーションを開発することが出来ます。
(余談)
API Gateway の Websocket 機能を確認する前では、「wss(or ws) プロトコルを中継する機能」程度に想像していました。
つまり、API Gateway と サーバー間も wss
(あたは ws
)で通信するものとばかり思っておりました。
調べてみると、上記の通りの実装であり、うまくできているなぁと目から鱗でした。
サーバー側から API Gateway を介して Websocket クライアントと通信を開始する
Websocket プロトコルの強みの一つは、サーバー側から通信を開始できる点です。
通信プロトコル周りで紹介したように、 API Gateway と サーバー間は REST API で通信します。
この点を踏まえ、この章では以下を確認します。
- サーバー側から、 REST API を使用して、クライアントと通信を開始する仕組み
- クライアントを識別する方法
サーバー側から通信を開始する
サーバー側から通信を開始する手段として、API Gateway の Websocketでは、@connections
コマンドという仕組みが用意されています。
以下は、クライアントへメッセージを送信する @connections
コマンドの例です。
//({connection_id} については後述)
POST https://{api-id}.execute-api.{region}.amazonaws.com/{stage}/@connections/{connection_id}
見ての通り、 @connections
というパスを含む API Gateway へ POST リクエストを送信しています。
つまり、@connections
というパスを含む API Gateway のエンドポイントへ (REST形式で)リクエストを送信することで、クライアントへの通信を実現します。
自力で POST リクエストを組み立てる他、AWS SDKに、 @connections
コマンド用のAPIが用意されています。
- https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/apigatewaymanagementapi/command/PostToConnectionCommand/
- https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-how-to-call-websocket-api-connections.html
次に、通信したいクライアントを識別する方法を確認します。
通信したいクライアントを識別する
クライアント識別するには、 connection_id
という情報を使用します。
クライアントを識別する手段として connection_id
という情報が用意されています。
各種 @connections
コマンドの詳細は、以下公式ドキュメントを参照ください。
"ルート" 情報で、転送先サーバー側アプリケーションを制御
クライアントから Websocket 通信を受け付けた API Gateway は、処理を行うサーバー側を制御できます。
API Gateway の Websocket API の文脈では、"ルート" と表現します。
Websocket メッセージの内容に応じて、ルートが自動で選択されます。
そして、ルート毎に、処理したいサーバー側アプリケーションを設定できます。
用意されているルートの種類と、その概説は以下の通りです。
ルート名 | 概説 |
---|---|
$connect ルート |
Websocket 接続が確立されたときに選択されるルート。接続確立時に実行したい処理は、このルートに紐づける。 |
$disconnect ルート |
Websocket 接続が切断されたときに選択されるルート。接続切断時に実行したい処理は、このルートに紐づける。 |
カスタムルート | 開発者が制御できるルート。メインとなる処理は、このルートに紐づける。 |
$default ルート |
上記のいずれにも該当しない場合に選択されるルート。 予期しないメッセージの処理等に活用する。 |
開発者が制御できる、 "カスタムルート" について、もう少し掘り下げます。
カスタムルートで、メインロジックを更に細かく制御
カスタムルートの仕組みは単純です。
Websocket メッセージ内の特定の値を参照して、ルートを制御します。
公式ドキュメントでは、"特定の値"に action
という名前を用いており、本記事もこれに倣います(もちろん、任意の値を設定することも可能です)。
そして、 action
プロパティの値に応じて、実行したいサーバー側アプリケーションを設定できます。
クォータ
公式ドキュメント に記載の通りです。
特に、以下のクォータには要注意です。
リソースまたはオペレーション | デフォルトのクォータ | 引き上げ可能 |
---|---|---|
WebSocket API の接続時間 | 2時間 | いいえ |
上記クォータは、一つの Websocket 接続単位で設けられます。
- 1接続辺り、 最大2時間接続可能
- 言い換えると、10接続だから 1接続辺り 12分 ... というわけではない
感想
API Gateway とサーバー間の通信に REST API を用いる点、最初は戸惑いましたが、理解が進むと色々とメリットが多いように感じました。
REST API に対応していれば、サーバーレスサービスも選択でき、 Lambdaに至っては Websocket APIと統合されています。
メインとなる処理も "カスタムルート" という仕組みで細かく制御可能で、 マイクロサービス化も容易に感じました。
また、試しに作成した過程を こちらの記事 にまとめました。
参考文献
- https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-websocket-api.html
- https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-how-to-call-websocket-api-connections.html
- https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-websocket-api-routes-integrations.html#apigateway-websocket-api-routes-about-custom
- https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/limits.html#apigateway-execution-service-websocket-limits-table
- https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/apigatewaymanagementapi/command/PostToConnectionCommand/
- https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-how-to-call-websocket-api-connections.html
Discussion