

# チュートリアル: WebSocket API、Lambda、DynamoDB を使用して WebSocket チャットアプリを作成する
<a name="websocket-api-chat-app"></a>

このチュートリアルでは、WebSocket API を使用してサーバーレスチャットアプリケーションを作成します。WebSocket API を使用すると、クライアント間の双方向通信をサポートできます。クライアントは、更新をポーリングしなくてもメッセージを受信できます。

このチュートリアルの完了には約 30 分かかります。最初に、CloudFormation テンプレートを使用して API リクエストを処理する Lambda 関数と、クライアント ID を保存する DynamoDB テーブルを作成します。次に、API Gateway コンソールを使用して、Lambda 関数と統合する WebSocket API を作成します。最後に、API をテストして、メッセージが送受信されることを確認します。

![\[このチュートリアルで作成する API のアーキテクチャの概要。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/ws-chat-app.png)


このチュートリアルを完了するには、AWS アカウントと、コンソールへのアクセス権がある AWS Identity and Access Management ユーザーが必要です。詳細については、「[API Gateway を使用するようにセットアップする](setting-up.md)」を参照してください。

また、API に接続するには `wscat` も必要です。詳細については、「[`wscat` を使用した WebSocket API への接続とメッセージの送信](apigateway-how-to-call-websocket-api-wscat.md)」を参照してください。

**Topics**
+ [ステップ 1: Lambda 関数と DynamoDB テーブルを作成する](#websocket-api-chat-app-create-dependencies)
+ [ステップ 2: WebSocket API を作成する](#websocket-api-chat-app-create-api)
+ [ステップ 3: API をテストする](#websocket-api-chat-app-invoke-api)
+ [ステップ 4: クリーンアップする](#websocket-api-chat-app-cleanup)
+ [次のステップ: CloudFormation を使用して自動化する](#websocket-api-chat-app-next-steps)

## ステップ 1: Lambda 関数と DynamoDB テーブルを作成する
<a name="websocket-api-chat-app-create-dependencies"></a>

[CloudFormation のアプリケーション作成テンプレート](samples/ws-chat-app-starter.zip)をダウンロードして解凍します。このテンプレートを使用して、アプリケーションのクライアント ID を保存する Amazon DynamoDB テーブルを作成します。接続されている各クライアントには、テーブルのパーティションキーとして使用する一意の ID があります。このテンプレートは、DynamoDB のクライアント接続を更新し、接続されたクライアントへのメッセージの送信を処理する Lambda 関数も作成します。

**CloudFormation スタックを作成するには**

1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソール を開きます。

1. [**スタックの作成**] を選択し、[**With new resources (standard) 新しいリソースを使用 (標準)**] を選択します。

1. [**Specify template (テンプレートの指定)**] で、[**Upload a template file (テンプレートファイルのアップロード)**] を選択します。

1. ダウンロードしたテンプレートを選択します。

1. [**Next (次へ)**] を選択します。

1. [**Stack name**] (スタックの名前) で、**websocket-api-chat-app-tutorial** と入力し、[**Next**] (次へ) を選択します。

1. [**Configure stack options**] (スタックオプションの設定) で、[**Next**] (次へ) を選択します。

1. [**Capabilities**] (機能) で、CloudFormation がアカウントに IAM リソースを作成できることを承認します。

1. **[次へ]** を選択し、**[送信]** を選択します。

CloudFormation は、テンプレートで指定されたリソースをプロビジョニングします。リソースのプロビジョニングには数分かかることがあります。CloudFormation スタックのステータスが **CREATE\$1COMPLETE** の場合は、次のステップに進む準備ができています。

## ステップ 2: WebSocket API を作成する
<a name="websocket-api-chat-app-create-api"></a>

WebSocket API を作成して、クライアント接続を処理し、ステップ 1 で作成した Lambda 関数にリクエストをルーティングします。



**WebSocket API を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**API の作成**] を選択します。次に、[**WebSocket API**] で [**Build**] (ビルド) を選択します

1. [**API 名**] に「**websocket-chat-app-tutorial**」と入力します。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

1. [**Route selection expression**] (ルート選択式) に「**request.body.action**」と入力します。ルート選択式は、クライアントがメッセージを送信したときに API Gateway が呼び出すルートを決定します。

1. [**次へ**] を選択します。

1. [**Predefined routes**] (定義済みのルート) で、[**Add \$1connect**] (\$1connect の追加)、[**Add \$1disconnect**] (\$1disconnect の追加)、および [**Add \$1default**] (\$1default の追加) を選択します。[**\$1connect**] および [**\$1disconnect**] ルートは、クライアントが API に接続または切断したときに API Gateway が自動的に呼び出す特別なルートです。API Gateway は、他のルートがリクエストに一致するルートがない場合に、`$default` ルートを呼び出します。

1. [**Custom routes**] (カスタムルート) で、[**Add custom route**] (カスタムルートの追加) を選択します。[**Route key**] (ルートキー) に「**sendmessage**」と入力します。このカスタムルートは、接続されたクライアントに送信されるメッセージを処理します。

1. [**次へ**] を選択します。

1. [**Attach integrations**] (統合のアタッチ) で、各ルートと [**Integration type**] (統合タイプ) ごとに、Lambda を選択します。

   [**Lambda**] には、ステップ 1 で CloudFormation を使用して作成した、対応する Lambda 関数を選択します。各関数の名前はルートと一致します。例えば、[**\$1connect**] ルートの場合は、**websocket-chat-app-tutorial-ConnectHandler** という名前の関数を選択します。

1. API Gateway が作成するステージを確認します。デフォルトでは、API Gateway はステージ名 `production` を作成し、API をそのステージに自動的にデプロイします。[**次へ**] を選択します。

1. [**Create and deploy**] (作成してデプロイ) を選択します。

## ステップ 3: API をテストする
<a name="websocket-api-chat-app-invoke-api"></a>

次に、API をテストして正しく動作していることを確認します。API に接続するには、`wscat` コマンドを使用します。

**API の呼び出し URL を取得するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API を選択します。

1. [**Stages**] (ステージ) を選択し、[**production**] (本稼働) を選択します。

1. API の [**WebSocket URL**] を書き留めます。URL は `wss://abcdef123.execute-api.us-east-2.amazonaws.com/production` のようになります。

**API に接続するには**

1. API に接続するには、以下のコマンドを使用します。API に接続すると、API Gateway は `$connect` ルートを呼び出します。このルートが呼び出されると、DynamoDB に接続 ID を保存する Lambda 関数が呼び出されます。

   ```
   wscat -c wss://abcdef123.execute-api.us-west-2.amazonaws.com/production
   ```

   ```
   Connected (press CTRL+C to quit)
   ```

1. 新しいターミナルを開き、次のパラメータを指定して **wscat** コマンドを再度実行します。

   ```
   wscat -c wss://abcdef123.execute-api.us-west-2.amazonaws.com/production
   ```

   ```
   Connected (press CTRL+C to quit)
   ```

   これにより、メッセージを交換できる 2 つの接続されたクライアントが提供されます。

**メッセージを送信するには**
+  API Gateway は、API のルート選択式に基づいて、呼び出すルートを決定します。API のルート選択式は `$request.body.action` です。その結果、API Gateway は次のメッセージを送信したときに `sendmessage` ルートを呼び出します。

  ```
  {"action": "sendmessage", "message": "hello, everyone!"}
  ```

  呼び出されたルートに関連付けられた Lambda 関数は、DynamoDB からクライアント ID を収集します。次に、Lambda 関数は API Gateway Management API を呼び出し、それらのクライアントにメッセージを送信します。接続されているすべてのクライアントが、次のメッセージを受け取ります。

  ```
  < hello, everyone!
  ```

**API の \$1default ルートを呼び出すには**
+ API Gateway は、定義されたルートと一致しないメッセージをクライアントが送信すると、API のデフォルトルートを呼び出します。`$default` ルートに関連付けられた Lambda 関数 は、API Gateway Management API を使用して、接続に関するクライアント情報を送信します。

  ```
  test
  ```

  ```
  Use the sendmessage route to send a message. Your info: {"ConnectedAt":"2022-01-25T18:50:04.673Z","Identity":{"SourceIp":"192.0.2.1","UserAgent":null},"LastActiveAt":"2022-01-25T18:50:07.642Z","connectionID":"Mg_ugfpqPHcCIVA="}
  ```

**API から切断するには**
+ API から切断するには、**CTRL\$1C** を押します。クライアントが API から切断されると、API Gateway は API の `$disconnect` ルートを呼び出します。API の `$disconnect` ルートの Lambda 統合は、DynamoDB から接続 ID を削除します。

## ステップ 4: クリーンアップする
<a name="websocket-api-chat-app-cleanup"></a>

不要なコストを回避するには、このチュートリアルで作成したリソースを削除します。次のステップでは、CloudFormation スタックと WebSocket API を削除します。

**WebSocket API を削除するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**API**] ページで `websocket-chat-app-tutorial` API を選択します。**[アクション]**、**[削除]** の順に選択し、選択を確定します。

**CloudFormation スタックを削除するには**

1. CloudFormation コンソール ([https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)) を開きます。

1. CloudFormation スタックを選択します。

1. [**Delete**] (削除) を選択し、選択を確定します。

## 次のステップ: CloudFormation を使用して自動化する
<a name="websocket-api-chat-app-next-steps"></a>

このチュートリアルで使用するすべての AWS リソースの作成とクリーンアップを自動化できます。この API とすべての関連リソースを作成する ‭CloudFormation テンプレートについては、‭「[ws-chat-app.yaml](samples/ws-chat-app.zip)」を参照してください。