このチュートリアルでは、WebSocket API を使用してサーバーレスブロードキャストアプリケーションを作成します。クライアントは、更新をポーリングしなくてもメッセージを受信できます。
このチュートリアルでは、接続しているクライアントにメッセージをブロードキャストする方法を示します。また、Lambda オーソライザー、Mock 統合、Step Functions への非プロキシ統合の例も含まれています。

AWS CloudFormation テンプレートを使用してリソースを作成したら、API Gateway コンソールを使用して、AWS リソースと統合する WebSocket API を作成します。Lambda オーソライザーを API にアタッチし、AWS のサービスと Step Functions の統合を作成して、ステートマシンの実行を開始します。Step Functions ステートマシンは Lambda 関数を呼び出し、接続しているすべてのクライアントにメッセージを送信します。
API を構築したら、API への接続をテストし、メッセージが送受信されることを確認します。このチュートリアルの完了には約 45 分かかります。
トピック
前提条件
次の前提条件を満たしている必要があります。
-
コンソールにアクセスできる AWS アカウントと AWS Identity and Access Management ユーザー。詳細については、「API Gateway を使用するようにセットアップする」を参照してください。
-
API に接続するための
wscat
。詳細については、「wscat を使用した WebSocket API への接続とメッセージの送信」を参照してください。
このチュートリアルを開始する前に、WebSocket チャットアプリケーションのチュートリアルを完了することをお勧めします。WebSocket チャットアプリケーションのチュートリアルを完了するには、「チュートリアル: WebSocket API、Lambda、DynamoDB を使用して WebSocket チャットアプリを作成する」を参照してください。
ステップ 1: リソースを作成する
AWS CloudFormation のアプリケーション作成テンプレートをダウンロードして解凍します。このテンプレートを使用して以下を作成します。
API リクエストを処理し、API へのアクセスを許可する Lambda 関数。
Lambda オーソライザーから返されるクライアント ID とプリンシパルユーザー ID を保存する DynamoDB テーブル。
接続しているクライアントにメッセージを送信する Step Functions ステートマシン。
AWS CloudFormation スタックを作成するには
https://console.aws.amazon.com/cloudformation
で AWS CloudFormation コンソール を開きます。 -
[スタックの作成] を選択し、[With new resources (standard) 新しいリソースを使用 (標準)] を選択します。
-
[Specify template (テンプレートの指定)] で、[Upload a template file (テンプレートファイルのアップロード)] を選択します。
-
ダウンロードしたテンプレートを選択します。
-
[Next (次へ)] を選択します。
-
[Stack name] (スタックの名前) で、
websocket-step-functions-tutorial
と入力し、[Next] (次へ) を選択します。 -
[Configure stack options] (スタックオプションの設定) で、[Next] (次へ) を選択します。
-
[Capabilities] (機能) で、AWS CloudFormation がアカウントに IAM リソースを作成できることを承認します。
-
[送信] を選択します。
AWS CloudFormation は、テンプレートで指定されたリソースをプロビジョニングします。リソースのプロビジョニングには数分かかることがあります。[出力] タブを選択して、作成したリソースとその ARN を表示します。AWS CloudFormation スタックのステータスが CREATE_COMPLETE の場合は、次のステップに進む準備ができています。
ステップ 2: WebSocket API を作成する
WebSocket API を作成して、クライアント接続を処理し、ステップ 1 で作成したリソースにリクエストをルーティングします。
WebSocket API を作成するには
https://console.aws.amazon.com/apigateway
で API Gateway コンソールにサインインします。 [API の作成] を選択します。次に、[WebSocket API] で [Build] (ビルド) を選択します
[API 名] に「
websocket-step-functions-tutorial
」と入力します。[Route selection expression] (ルート選択式) に「
request.body.action
」と入力します。ルート選択式は、クライアントがメッセージを送信したときに API Gateway が呼び出すルートを決定します。
[Next] を選択します。
[事前定義されたルート] で、[$connect を追加]、[$disconnect を追加]、[$default を追加] を選択します。
$connect ルートと $disconnect ルートは、クライアントが API との接続または切断を行ったときに、API Gateway が自動的に呼び出す特別なルートです。API Gateway は、リクエストと一致するルートがないと、$default ルートを呼び出します。API を作成したら、Step Functions に接続するためのカスタムルートを作成します。
[Next] を選択します。
[$connect の統合] で、次の操作を行います。
[統合タイプ] で、[Lambda] を選択します。
-
[Lambda 関数] で、ステップ 1 で AWS CloudFormation によって作成した該当する $connect Lambda 関数を選択します。Lambda 関数名は
websocket-step
で始まる必要があります。
[$disconnect の統合] で、次の操作を行います。
[統合タイプ] で、[Lambda] を選択します。
-
[Lambda 関数] で、ステップ 1 で AWS CloudFormation によって作成した該当する $disconnect Lambda 関数を選択します。Lambda 関数名は
websocket-step
で始まる必要があります。
[$default の統合] で、[Mock] を選択します。
Mock 統合の場合、API Gateway は統合バックエンドなしでルートレスポンスを管理します。
[Next] を選択します。
-
API Gateway が作成するステージを確認します。デフォルトでは、API Gateway は production という名前のステージを作成し、このステージに API を自動的にデプロイします。[Next] を選択します。
[Create and deploy] (作成してデプロイ) を選択します。
ステップ 3: Lambda オーソライザーを作成する
WebSocket API へのアクセスを制御するには、Lambda オーソライザーを作成します。Lambda オーソライザー関数は、AWS CloudFormation テンプレートで自動的に作成されています。この Lambda 関数は、Lambda コンソールで確認できます。名前は websocket-step-functions-tutorial-AuthorizerHandler
で始まります。この Lambda 関数は、Authorization
ヘッダーが Allow
である場合を除いて、WebSocket API へのすべての呼び出しを拒否します。また、Lambda 関数は $context.authorizer.principalId
変数を API に渡します。この変数は、後で DynamoDB テーブルで API の呼び出し元を識別するために使用します。
このステップでは、Lambda オーソライザーを使用するように $connect ルートを設定します。
Lambda オーソライザーを作成するには
https://console.aws.amazon.com/apigateway
で API Gateway コンソールにサインインします。 メインナビゲーションペインで、[オーソライザー] を選択します。
[オーソライザーを作成] を選択します。
[オーソライザー名] に、「
LambdaAuthorizer
」と入力します。[オーソライザー ARN] に、AWS CloudFormation テンプレートで作成したオーソライザーの名前を入力します。名前は
websocket-step-functions-tutorial-AuthorizerHandler
で始まります。注記
このサンプルオーソライザーは、本稼働用 API で使用しないことをお勧めします。
[ID ソースタイプ] で、[ヘッダー] を選択します。[Key] (キー) に「
Authorization
」と入力します。[オーソライザーの作成] を選択します。
オーソライザーを作成したら、API の $connect ルートにアタッチします。
オーソライザーを $connect ルートにアタッチするには
メインナビゲーションペインで、[ルート] を選択します。
[$connect] ルートを選択します。
[ルートリクエストの設定] セクションで、[編集] を選択します。
[認可] で、ドロップダウンメニューを選択し、リクエストオーソライザーを選択します。
[変更を保存] を選択します。
ステップ 4: Mock 双方向統合を作成する
次に、$default ルートの双方向 Mock 統合を作成します。Mock 統合では、バックエンドを使用することなく、クライアントにレスポンスを送信できます。$default ルートの統合を作成すると、API の操作方法をクライアントに示すことができます。
クライアントに sendmessage ルートを使用することを通知するように $default ルートを設定します。
Mock 統合を作成するには
https://console.aws.amazon.com/apigateway
で API Gateway コンソールにサインインします。 $default ルートを選択し、[統合リクエスト] タブを選択します。
[リクエストテンプレート] で、[編集] を選択します。
[テンプレート選択式] に「
200
」と入力して、[編集] を選択します。[統合リクエスト] タブの [リクエストテンプレート] で、[テンプレートを作成] を選択します。
[テンプレートキー] に「
200
」と入力します。[テンプレートを生成] で、次のマッピングテンプレートを入力します。
{"statusCode": 200}
[テンプレートを作成] をクリックします。
結果は次のようになります。
[$default ルート] ペインで、[双方向通信を有効にする] を選択します。
[統合レスポンス] タブ、[統合レスポンスを作成] の順に選択します。
[レスポンスキー] に「
$default
」と入力します 。[テンプレート選択式] に「
200
」と入力します。[レスポンスの作成] を選択します。
[レスポンステンプレート] で、[テンプレートを作成] を選択します。
[テンプレートキー] に「
200
」と入力します。[レスポンステンプレート] に、次のマッピングテンプレートを入力します。
{"Use the sendmessage route to send a message. Connection ID: $context.connectionId"}
[テンプレートを作成] をクリックします。
結果は次のようになります。
ステップ 5: Step Functions で非プロキシ統合を作成する
次に、sendmessage ルートを作成します。クライアントは、sendmessage ルートを呼び出して、接続しているすべてのクライアントにメッセージをブロードキャストできます。sendmessage ルートには、AWS のサービスと AWS Step Functions の非プロキシ統合が含まれています。この統合は、AWS CloudFormation テンプレートで自動的に作成した Step Functions ステートマシンに対して StartExecution コマンドを呼び出します。
非プロキシ統合を作成するには
https://console.aws.amazon.com/apigateway
で API Gateway コンソールにサインインします。 [ルートの作成] を選択します。
[Route key] (ルートキー) に「
sendmessage
」と入力します。[統合タイプ] で、[AWS のサービス] を選択します。
[AWS リージョン] に、AWS CloudFormation テンプレートをデプロイしたリージョンを入力します。
[AWS のサービス] で、[Step Functions] を選択します。
[HTTP メソッド] で、[POST] を選択します。
[アクション名] に「
StartExecution
」と入力します。[実行ロール] に、AWS CloudFormation テンプレートで作成した実行ロールを入力します。名前は WebSocketTutorialApiRole にする必要があります。
[ルートの作成] を選択します。
次に、Step Functions ステートマシンにリクエストパラメータを送信するためのマッピングテンプレートを作成します。
マッピングテンプレートを作成するには
sendmessage ルートを選択し、[統合リクエスト] タブを選択します。
[リクエストテンプレート] セクションで、[編集] を選択します。
[テンプレート選択式] に「
\$default
」と入力します。[編集] を選択します。
[リクエストテンプレート] セクションで、[テンプレートを作成] を選択します。
[テンプレートキー] に「
\$default
」と入力します。[テンプレートを生成] で、次のマッピングテンプレートを入力します。
#set($domain = "$context.domainName") #set($stage = "$context.stage") #set($body = $input.json('$')) #set($getMessage = $util.parseJson($body)) #set($mymessage = $getMessage.message) { "input": "{\"domain\": \"$domain\", \"stage\": \"$stage\", \"message\": \"$mymessage\"}", "stateMachineArn": "arn:aws:states:
us-east-2
:123456789012
:stateMachine:WebSocket-Tutorial-StateMachine" }stateMachineArn
を、AWS CloudFormation で作成したステートマシンの ARN に置き換えます。マッピングテンプレートは、次の操作を行います。
-
コンテキスト変数
domainName
を使用して変数$domain
を作成します。 -
コンテキスト変数
stage
を使用して変数$stage
を作成します。コールバック URL を作成するには、
$domain
変数と$stage
変数が必要です。 着信する
sendmessage
JSON メッセージを取り込み、message
プロパティを抽出します。-
ステートマシンの入力を作成します。入力は、WebSocket API のドメインとステージ、および
sendmessage
ルートからのメッセージです。
-
-
[テンプレートを作成] をクリックします。
非プロキシ統合を $connect ルートまたは $disconnect ルートで作成し、Lambda 関数を呼び出すことなく、DynamoDB テーブルの接続 ID を直接追加または削除できます。
ステップ 6: API をテストする
次に、API をデプロイしてテストし、正しく動作することを確認します。wscat
コマンドを使用して API に接続し、スラッシュコマンドで ping フレームを送信して WebSocket API への接続をチェックします。
API をデプロイするには
https://console.aws.amazon.com/apigateway
で API Gateway コンソールにサインインします。 メインナビゲーションペインで、[ルート] を選択します。
[API のデプロイ] を選択します。
[ステージ] で、[production] を選択します。
(オプション)[デプロイの説明] に説明を入力します。
[デプロイ] を選択します。
API をデプロイしたら、これを呼び出すことができます。API を呼び出すには、呼び出し URL を使用します。
API の呼び出し URL を取得するには
API を選択します。
[Stages] (ステージ) を選択し、[production] (本稼働) を選択します。
-
API の [WebSocket URL] を書き留めます。URL は
wss://
のようになります。abcdef123
.execute-api.us-east-2
.amazonaws.com/production
呼び出し URL を取得したので、WebSocket API への接続をテストできます。
API への接続をテストするには
API に接続するには、以下のコマンドを使用します。まず、
/ping
パスを呼び出して接続をテストします。wscat -c wss://
abcdef123
.execute-api.us-east-2
.amazonaws.com/production -H "Authorization: Allow" --slash -PConnected (press CTRL+C to quit)
-
次のコマンドを入力してコントロールフレームに ping を送信します。コントロールフレームは、クライアント側からのキープアライブ目的に使用できます。
/ping
結果は次のようになります。
< Received pong (data: "")
接続のテストが完了したので、API が正しく動作することをテストできます。このステップでは、新しいターミナルウィンドウを開いて、接続しているすべてのクライアントに WebSocket API からメッセージを送信できるようにします。
API をテストするには
-
新しいターミナルを開き、次のパラメータを指定して
wscat
コマンドを再度実行します。wscat -c wss://
abcdef123
.execute-api.us-east-2
.amazonaws.com/production -H "Authorization: Allow"Connected (press CTRL+C to quit)
-
API Gateway は、API のルートリクエスト選択式に基づいて、どのルートを呼び出すかを決定します。API のルート選択式は
$request.body.action
です。その結果、API Gateway は次のメッセージを送信したときにsendmessage
ルートを呼び出します。{"action": "sendmessage", "message": "hello, from Step Functions!"}
ルートに関連する Step Functions ステートマシンは、メッセージとコールバック URL を使用して Lambda 関数を呼び出します。Lambda 関数は API Gateway 管理 API を呼び出し、接続しているすべてのクライアントにメッセージを送信します。すべてのクライアントは、次のメッセージを受け取ります。
< hello, from Step Functions!
WebSocket API のテストが完了したので、API との接続を切断できます。
API から切断するには
API から切断するには、
CTRL+C
を押します。クライアントが API から切断すると、API Gateway は API の $disconnect ルートを呼び出します。API の $disconnect ルートの Lambda 統合は、DynamoDB から接続 ID を削除します。
ステップ 7: クリーンアップする
不要なコストを回避するには、このチュートリアルで作成したリソースを削除します。次のステップでは、AWS CloudFormation スタックと WebSocket API を削除します。
WebSocket API を削除するには
https://console.aws.amazon.com/apigateway
で API Gateway コンソールにサインインします。 [API] ページで、[websocket-api] を選択します。
[アクション]、[削除] の順に選択し、選択を確定します。
AWS CloudFormation スタックを削除するには
AWS CloudFormation コンソール (https://console.aws.amazon.com/cloudformation
) を開きます。 -
AWS CloudFormation スタックを選択します。
-
[Delete] (削除) を選択し、選択を確定します。
次のステップ
このチュートリアルに関連するすべての AWS リソースの作成とクリーンアップは自動化できます。このチュートリアルでこれらのアクションを自動化する AWS CloudFormation テンプレートの例については、「ws-sfn.zip」を参照してください。