

# API Gateway WebSocket API
<a name="apigateway-websocket-api"></a>

API Gateway の WebSocket API は、バックエンドの HTTP エンドポイント、Lambda 関数、またはその他の AWS のサービスを使用して統合されている WebSocket ルートのコレクションです。API Gateway 機能を使用すると、作成から本番稼働 API のモニタリングまで、API ライフサイクルのあらゆる側面を支援できます。

API Gateway WebSocket API は双方向です。クライアントはサービスにメッセージを送信し、サービスは個別にクライアントにメッセージを送信できます。この双方向動作により、クライアントが明示的な要求を行う必要がなく、サービスがクライアントにデータをプッシュできるため、より豊かなクライアント/サービスの対話が実現します。WebSocket API は、チャットアプリケーション、コラボレーションプラットフォーム、マルチプレイヤーゲーム、金融取引プラットフォームなどのリアルタイムアプリケーションでよく使用されます。

開始するためのサンプルアプリについては、「[チュートリアル: WebSocket API、Lambda、DynamoDB を使用して WebSocket チャットアプリを作成する](websocket-api-chat-app.md)」を参照してください。

このセクションでは、API Gateway を使用して WebSocket API を開発、公開、保護、監視する方法を学習できます。

**Topics**
+ [API Gateway での WebSocket API の概要](apigateway-websocket-api-overview.md)
+ [API Gateway で WebSocket API を開発する](websocket-api-develop.md)
+ [WebSocket API を公開してユーザーが呼び出せるようにする](websocket-api-publish.md)
+ [API Gateway で WebSocket API を保護する](websocket-api-protect.md)
+ [API Gateway で WebSocket API をモニタリングする](websocket-api-monitor.md)

# API Gateway での WebSocket API の概要
<a name="apigateway-websocket-api-overview"></a>

API Gateway では、AWS のサービス (Lambda や DynamoDB など) または HTTP エンドポイントのステートフルフロントエンドとして WebSocket API を作成できます。WebSocket API は、クライアントアプリから受信するメッセージのコンテンツに基づいて、バックエンドを呼び出します。

WebSocket API は、リクエストを受け取って応答する REST API とは異なり、クライアントアプリとバックエンド間の双方向通信をサポートします。バックエンドは、接続されたクライアントにコールバックメッセージを送信できます。

WebSocket API では、受信する JSON メッセージは設定したルートに基づいてバックエンド統合に転送されます (JSON 以外のメッセージは、設定した `$default` ルートに転送されます)。

*ルート*には*ルートキー*が含まれます。これは、*ルート選択式*が評価されたときに予期される値です。属性 `routeSelectionExpression` は、API レベルで定義されます。メッセージペイロードに存在することが予期される JSON プロパティを指定します。ルート選択式の詳細については、「[ルート選択式](websocket-api-develop-routes.md#apigateway-websocket-api-route-selection-expressions)」を参照してください。

たとえば、JSON メッセージに `action` プロパティが含まれていて、このプロパティに基づいてさまざまなアクションを実行する場合、ルート選択式は `${request.body.action}` のようになります。ルーティングテーブルでは、このテーブルで定義したカスタムルートキーの値に対して、`action` プロパティの値を一致させることによって、実行するアクションを指定します。

## WebSocket API のルートを使用する
<a name="apigateway-websocket-api-overview-routes"></a>

3 つの事前定義されたルート (`$connect`、`$disconnect`、および `$default`) を使用できます。さらに、カスタムルートを作成することができます。
+ API Gateway は、クライアントと WebSocket API 間の永続的な接続が開始されたときに、`$connect` ルートを呼び出します。
+ API Gateway は、クライアントまたはサーバーが API から切断したときに、`$disconnect` ルートを呼び出します。
+ API Gateway は、一致するルートが見つかった場合、メッセージに対してルート選択式が評価された後でカスタムルートを呼び出します。この一致により、呼び出される統合が決まります。
+ ルート選択式をメッセージに対して評価できない場合や、一致するルートが見つからない場合、API Gateway は `$default` ルートを呼び出します。

`$connect` および `$disconnect` ルートの詳細については、「[接続されたユーザーとクライアントアプリを管理する: `$connect` ルートおよび `$disconnect` ルート](apigateway-websocket-api-route-keys-connect-disconnect.md)」を参照してください。

`$default` ルートおよびカスタムルートの詳細については、「[API Gateway の `$default` ルートおよびカスタムルートを使用してバックエンド統合を呼び出す](apigateway-websocket-api-routes-integrations.md)」を参照してください。

## 接続されたクライアントアプリケーションにデータを送信する
<a name="apigateway-websocket-api-overview-send-data"></a>

バックエンドサービスは、接続されたクライアントアプリにデータを送信できます。以下を実行することにより、データを送信できます。
+ 統合を使用してレスポンスを送信します。レスポンスは、定義したルートレスポンスでクライアントに返されます。
+ `@connections` API を使用して POST リクエストを送信することができます。詳細については、「[バックエンドサービスでの `@connections` コマンドの使用](apigateway-how-to-call-websocket-api-connections.md)」を参照してください。

## WebSocket API ステータスコード
<a name="apigateway-websocket-status-codes"></a>

API Gateway WebSocket API は、[WebSocket Close Code Number Registry](https://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number) に説明されているように、サーバーからクライアントへの通信に次のステータスコードを使用します。

1001  
API Gateway は、クライアントが 10 分間アイドル状態であるか、最大 2 時間の接続の存続時間に達したときに、このステータスコードを返します。

1003  
API Gateway は、エンドポイントがバイナリメディアタイプを受信すると、このステータスコードを返します。バイナリメディアタイプは WebSocket API ではサポートされていません。

1005  
API Gateway は、クライアントがクローズコードなしでクローズフレームを送信すると、このステータスコードを返します。

1006  
API Gateway は、WebSocket クローズフレームなしで TCP 接続が閉じられるなど、接続が予期せず閉じられた場合、このステータスコードを返します。

1008  
API Gateway は、エンドポイントが特定のクライアントから受信したリクエストが多すぎると、このステータスコードを返します。

1009  
API Gateway は、エンドポイントが処理するには大きすぎるメッセージを受信すると、このステータスコードを返します。

1011  
API Gateway は、内部サーバーエラーが発生したときに、このステータスコードを返します。

1012  
サービスが再起動すると、API Gateway はこのステータスコードを返します。

# 接続されたユーザーとクライアントアプリを管理する: `$connect` ルートおよび `$disconnect` ルート
<a name="apigateway-websocket-api-route-keys-connect-disconnect"></a>

次のセクションでは、WebSocket API の `$connect` ルートおよび `$disconnect` ルートを使用する方法について説明します。

**Topics**
+ [`$connect` ルート](#apigateway-websocket-api-routes-about-connect)
+ [`$connect` ルートからの接続情報の受け渡し](#apigateway-websocket-api-passing-connectionId-on-connect)
+ [`$disconnect` ルート](#apigateway-websocket-api-routes-about-disconnect)

## `$connect` ルート
<a name="apigateway-websocket-api-routes-about-connect"></a>

クライアントアプリは、WebSocket アップグレードリクエストを送信して WebSocket API に接続します。リクエストが成功すると、接続が確立されている間に `$connect` ルートが実行されます。

WebSocket 接続はステートフルな接続であるため、`$connect` ルートのみで認可を設定できます。`AuthN`/`AuthZ` は接続時にのみ実行されます。

`$connect` ルートに関連付けられている統合の実行が完了するまで、アップグレードリクエストは保留中になり、実際の接続は確立されません。`$connect` リクエストが失敗した場合 (`AuthN`/`AuthZ` の障害や統合の障害など)、接続は行われません。

**注記**  
`$connect` で承認が失敗した場合、接続は確立されず、クライアントは `401` または `403` レスポンスを受け取ります。

`$connect` の統合の設定はオプションです。次の場合は `$connect` 統合の設定を検討してください。
+ `Sec-WebSocket-Protocol` フィールドを使用して、クライアントがサブプロトコルを指定できるようにする。サンプルコードについては、「[WebSocket サブプロトコルを必要とする `$connect` ルートを設定する](websocket-connect-route-subprotocol.md)」を参照してください。
+ クライアントが接続したときに通知を受ける。
+ 接続をスロットリングする、または接続するユーザーを管理する。
+ バックエンドで、コールバック URL を使用してメッセージをクライアントに送信する。
+ 各接続 ID およびその他の情報をデータベース (例: Amazon DynamoDB) に保存する。

## `$connect` ルートからの接続情報の受け渡し
<a name="apigateway-websocket-api-passing-connectionId-on-connect"></a>

 プロキシ統合と非プロキシ統合の両方を使用して、`$connect` ルートからデータベースまたは他の AWS のサービス に情報を渡すことができます。

### プロキシ統合を使用して接続情報を渡すには
<a name="websocket-connect-proxy-integration"></a>

イベントでは、Lambda プロキシ統合から接続情報にアクセスできます。別の AWS のサービス または AWS Lambda 関数を使用して接続に投稿します。

次の Lambda 関数は、`requestContext` オブジェクトを使用して接続 ID、ドメイン名、ステージ名、およびクエリ文字列を記録する方法を示しています。

------
#### [ Node.js ]

```
 export const handler = async(event, context) => {
    const connectId = event["requestContext"]["connectionId"]
    const domainName = event["requestContext"]["domainName"]
    const stageName = event["requestContext"]["stage"]
    const qs = event['queryStringParameters']
    console.log('Connection ID: ', connectId, 'Domain Name: ', domainName, 'Stage Name: ', stageName, 'Query Strings: ', qs )
    return {"statusCode" : 200}
};
```

------
#### [ Python ]

```
import json
import logging
logger = logging.getLogger()
logger.setLevel("INFO")


def lambda_handler(event, context):
    connectId = event["requestContext"]["connectionId"]
    domainName = event["requestContext"]["domainName"]
    stageName = event["requestContext"]["stage"]
    qs = event['queryStringParameters']
    connectionInfo = {
        'Connection ID': connectId,
        'Domain Name': domainName,
        'Stage Name': stageName,
        'Query Strings': qs}
    logging.info(connectionInfo)
    return {"statusCode": 200}
```

------

### 非プロキシ統合を使用して接続情報を渡すには
<a name="websocket-connect-non-proxy-integration"></a>
+ 非プロキシ統合により接続情報にアクセスできます。統合リクエストを設定し、WebSocket API リクエストテンプレートを提供します。以下の、[Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) マッピングテンプレートは、統合リクエストを提供します。このリクエストは、以下の詳細を非プロキシ統合に送信します。
  + 接続 ID
  + ドメイン名
  + ステージ名
  + パス
  + ヘッダー
  + クエリ文字列

  このリクエストは、接続 ID、ドメイン名、ステージ名、パス、ヘッダー、クエリ文字列を非プロキシ統合に送信します。

  ```
  {
      "connectionId": "$context.connectionId",
      "domain": "$context.domainName",
      "stage": "$context.stage",
      "params": "$input.params()"
  }
  ```

  データ変換の設定の詳細については、「[API Gateway での WebSocket API のデータ変換](websocket-api-data-transformations.md)」を参照してください。

  統合リクエストを完了するには、統合レスポンスに `StatusCode: 200` を設定します。統合レスポンスの詳しい設定方法については、「[API Gateway コンソールを使用した統合レスポンスの設定](apigateway-websocket-api-integration-responses.md#apigateway-websocket-api-integration-response-using-console)」を参照してください。

## `$disconnect` ルート
<a name="apigateway-websocket-api-routes-about-disconnect"></a>

`$disconnect` ルートは、接続を閉じた後に実行されます。

接続は、サーバーまたはクライアントによって閉じることができます。接続が実行されると、接続がすでに閉じられているため、`$disconnect` がベストエフォート型のイベントです。API Gateway は、統合に `$disconnect` イベントを配信するために最善を尽くしますが、配信を保証することはできません。

バックエンドは、`@connections` API を使用して切断を開始できます。詳細については、「[バックエンドサービスでの `@connections` コマンドの使用](apigateway-how-to-call-websocket-api-connections.md)」を参照してください。

# API Gateway の `$default` ルートおよびカスタムルートを使用してバックエンド統合を呼び出す
<a name="apigateway-websocket-api-routes-integrations"></a>

次のセクションでは、WebSocket API の `$default` ルートまたはカスタムルートを使用してバックエンド統合を呼び出す方法について説明します。

**Topics**
+ [ルートを使用したメッセージの処理](#apigateway-websocket-api-overview-routes)
+ [`$default` ルート](#apigateway-websocket-api-routes-about-default)
+ [カスタムルート](#apigateway-websocket-api-routes-about-custom)
+ [API Gateway WebSocket API 統合を使用したビジネスロジックへの接続](#apigateway-websocket-api-overview-integrations)
+ [WebSocket API と REST API の重要な相違点](#apigateway-websocket-api-overview-integrations-differences)

## ルートを使用したメッセージの処理
<a name="apigateway-websocket-api-overview-routes"></a>

API Gateway WebSocket API では、クライアントからバックエンドサービスに、またはその逆にメッセージを送信できます。HTTP のリクエスト/レスポンスモデルとは異なり、WebSocket ではクライアントがアクションを実行することなく、バックエンドがクライアントにメッセージを送信できます。

メッセージの形式は JSON または JSON 以外とすることができます。ただし、メッセージの内容によっては、JSON メッセージのみを特定の統合にルーティングできます。JSON 以外のメッセージは、`$default` ルートによってバックエンドにパススルーされます。

**注記**  
API Gateway は最大 128 KB までのメッセージペイロードをサポートし、最大フレームサイズは 32 KB です。メッセージが 32 KB を超えた場合は、それぞれが 32 KB 以下の複数のフレームに分割する必要があります。大きなメッセージ (またはフレーム) が受信された場合、接続は 1009 コードで閉じられます。  
現時点では、バイナリペイロードはサポートされていません。バイナリフレームが受信された場合、接続は 1003 コードで閉じられます。ただし、バイナリペイロードはテキストに変換できます。「[API Gateway での WebSocket API のバイナリメディアタイプ](websocket-api-develop-binary-media-types.md)」を参照してください。

API Gateway の WebSocket API では、メッセージの内容に基づいて JSON メッセージをルーティングし、特定のバックエンドサービスを実行できます。クライアントが WebSocket 接続経由でメッセージを送信すると、これが WebSocket API に対する*ルートリクエスト*になります。リクエストが、API Gateway の対応するルートキーを持つルートと照合されます。WebSocket API のルートリクエストは、API Gateway コンソールで、または AWS CLI もしくは AWS SDK を使用してセットアップできます。

**注記**  
AWS CLI および AWS SDK で、統合を作成する前または後にルートを作成できます。現在のところ、コンソールは統合の再利用をサポートしていないため、最初にルートを作成してから、そのルートの統合を作成する必要があります。

統合リクエストを進める前にルートリクエストの検証を実行するよう API Gateway を設定できます。検証に失敗すると、API Gateway はバックエンドを呼び出さずにリクエストを失敗させ、次のような `"Bad request body"` ゲートウェイレスポンスをクライアントに送信し、CloudWatch Logs で検証の失敗を発行します。

```
{"message" : "Bad request body", "connectionId": "{connectionId}", "messageId": "{messageId}"}
```

これによりバックエンドへの不要な呼び出しが減り、API のその他の要件に集中することができます。

また、API のルートに対するルートのレスポンスを定義し、双方向通信を有効にすることもできます。ルートレスポンスは、特定のルートの統合の完了時にどのようなデータがクライアントに送信されるかを示します。たとえば、クライアントがレスポンスを受信せずにバックエンドにレスポンスを送信するようにする場合 (単方向通信)、ルートのレスポンスを定義する必要はありません。ただし、ルートレスポンスのルートを提供しない場合、API Gateway は統合の結果に関する情報をクライアントに送信しません。

## `$default` ルート
<a name="apigateway-websocket-api-routes-about-default"></a>

すべての API Gateway WebSocket API は、`$default` ルートを持つことができます。これは、次の方法で使用できる特殊なルーティング値です。
+ これを定義されたルートキーと一緒に使用し、定義されたいずれのキーとも一致しない受信メッセージの「フォールバック」ルート (たとえば、特定のエラーメッセージを返す汎用モック統合) を指定できます。
+ 定義されたルートキーなしでこれを使用し、バックエンドコンポーネントにルーティングを委任するプロキシモデルを指定できます。
+ これを使用して、JSON 以外のペイロードのルートを指定できます。

## カスタムルート
<a name="apigateway-websocket-api-routes-about-custom"></a>

メッセージの内容に基づいて特定の統合を呼び出す場合、カスタムルートを作成してこれを行うことができます。

カスタムルートは、指定されたルートキーと統合を使用します。受信メッセージにプロパティ JSON プロパティが含まれていて、そのプロパティがルートキーの値に一致する値に評価される場合、API Gateway は統合を呼び出します。(詳しくは、[API Gateway での WebSocket API の概要](apigateway-websocket-api-overview.md) を参照してください)。

たとえば、チャットルームアプリケーションを作成するとします。ルート選択式が `$request.body.action` である WebSocket API を作成して開始できます。次に、`joinroom` および `sendmessage` の 2 つのルートを定義できます。クライアントアプリは、次のようなメッセージを送信して `joinroom` ルートを呼び出す場合があります。

```
{"action":"joinroom","roomname":"developers"}
```

また、次のようなメッセージを送信して `sendmessage` ルートを呼び出す場合があります。

```
{"action":"sendmessage","message":"Hello everyone"}
```

## API Gateway WebSocket API 統合を使用したビジネスロジックへの接続
<a name="apigateway-websocket-api-overview-integrations"></a>

API Gateway WebSocket API のルートを設定したら、使用する統合を指定する必要があります。ルートリクエストとルートレスポンスを持つことができるルートと同じように、統合は*統合リクエスト*と*統合レスポンス*を持つことができます。*統合リクエスト*には、クライアントから受け取ったリクエストを処理するためにバックエンドで予期される情報が含まれます。*統合レスポンス*には、バックエンドが API Gateway に返すデータが含まれます。このデータは、クライアントに送信するメッセージを作成するために使用される場合があります (ルートレスポンスが定義されている場合)。

統合の設定の詳細については、「[API Gateway での WebSocket API の統合](apigateway-websocket-api-integrations.md)」を参照してください。

## WebSocket API と REST API の重要な相違点
<a name="apigateway-websocket-api-overview-integrations-differences"></a>

WebSocket API の統合は REST API の統合に似ていますが、次のような違いがあります。
+ 現時点では、API Gateway コンソールで最初にルートを作成してから、そのルートのターゲットとして統合を作成する必要があります。ただし、API と CLI では、ルートと統合を任意の順序で個別に作成できます。
+ 複数のルートに単一の統合を使用できます。たとえば、相互に密接に関連した一連のアクションがある場合は、それらのすべてのルートを単一の Lambda 関数に移動したい場合があります。統合の詳細を複数回定義する代わりに、1 回指定して、関連する各ルートに割り当てることができます。
**注記**  
現在のところ、コンソールは統合の再利用をサポートしていないため、最初にルートを作成してから、そのルートの統合を作成する必要があります。  
AWS CLI、AWS SDK では、ルートのターゲットを `"integrations/{integration-id}"` の値に設定して統合を再利用できます。ここで `{integration-id}"` は、ルートに関連付ける統合の一意の ID です。
+ API Gateway は、ルートと統合で使用できる複数の[選択式](apigateway-websocket-api-selection-expressions.md)を提供します。入力テンプレートまたは出力マッピングを選択するために、コンテンツタイプに依存する必要はありません。ルート選択式の場合と同様に、API Gateway で評価される選択式を定義して、適切な項目を選択できます。それらのすべては、一致するテンプレートが見つからない場合に、`$default` テンプレートにフォールバックされます。
  + 統合リクエストで、テンプレート選択式は `$request.body.<json_path_expression>` および静的な値をサポートしています。
  + 統合レスポンスで、テンプレート選択式は `$request.body.<json_path_expression>`、`$integration.response.statuscode`、`$integration.response.header.<headerName>`、および静的な値をサポートします。

リクエストとレスポンスが同期的に送信される HTTP プロトコルでは、通信は基本的に一方向です。WebSocket プロトコルでは、通信は双方向です。レスポンスは非同期であり、必ずしもクライアントのメッセージの送信と同じ順序でクライアントによって受信される必要はありません。さらに、バックエンドはクライアントにメッセージを送信できます。

**注記**  
`AWS_PROXY` または `LAMBDA_PROXY` 統合を使用するように設定されたルートでは、通信は一方向で、API Gateway は自動的にルートレスポンスにバックエンドレスポンスをパススルーしません。たとえば、`LAMBDA_PROXY` 統合の場合は、 Lambda 関数が返す本文はクライアントに返されません。クライアントが統合レスポンスを受信するには、ルートレスポンスを定義して、双方向通信を可能にする必要があります。

# WebSocket 選択式
<a name="apigateway-websocket-api-selection-expressions"></a>

API Gateway はリクエストとレスポンスのコンテキストを評価し、キーを生成する方法として、選択式を使用します。次に、このキーを使用して、通常は API デベロッパーから提供される使用可能な値のセットから選択できます。サポートされている正確な変数のセットは、式によって異なります。各式については、以下で詳しく説明します。

すべての式では、言語は一連のルールに従います。
+ 変数には `"$"` が前に付けられます。
+ 中かっこを使用して、変数の境界を明示的に定義できます (例: `"${request.body.version}-beta"`)。
+ 複数の変数がサポートされていますが、評価は 1 回しか発生しません (繰り返しの評価は行われません)。
+ ドル記号 (`$`) を使って `"\"` をエスケープすることができます。これは、予約された `$default` キー (例: `"\$default"`) にマッピングされる式を定義するときに最も便利です。
+ 場合によっては、パターン形式が必要です。この場合、式は `"/"` のようにスラッシュ (`"/2\d\d/"`) で囲み、`2XX` のステータスコードに合わせる必要があります。

**Topics**
+ [ルートレスポンス選択式](#apigateway-websocket-api-route-response-selection-expressions)
+ [API キー選択式](#apigateway-websocket-api-apikey-selection-expressions)
+ [API マッピング選択式](#apigateway-websocket-api-mapping-selection-expressions)
+ [WebSocket 選択式の概要](#apigateway-websocket-api-selection-expression-table)

## ルートレスポンス選択式
<a name="apigateway-websocket-api-route-response-selection-expressions"></a>

[ルートレスポンス](apigateway-websocket-api-route-response.md)は、バックエンドからクライアントにレスポンスをモデル化するために使用されます。WebSocket API の場合、ルートレスポンスはオプションです。定義された場合、WebSocket メッセージを受信したときにレスポンスをクライアントに返す必要があることを API Gateway に指定します。

*ルートレスポンス選択式*の評価により、ルートレスポンスキーが生成されます。最終的に、このキーを使用して、API に関連付けられたいずれかの [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-routes-routeid-routeresponses.html](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-routes-routeid-routeresponses.html) から選択されます。ただし、現在サポートされているのは `$default` キーのみです。

## API キー選択式
<a name="apigateway-websocket-api-apikey-selection-expressions"></a>

この式は、クライアントが有効な [API キー](api-gateway-basic-concept.md#apigateway-definition-api-key)を提供した場合のみ、特定のリクエストを続行する必要があるとサービスが決定したときに評価されます。

現在サポートされている値は、`$request.header.x-api-key` および `$context.authorizer.usageIdentifierKey` の 2 つのみです。

## API マッピング選択式
<a name="apigateway-websocket-api-mapping-selection-expressions"></a>

この式は、カスタムドメインを使用してリクエストが実行されたときに選択する API ステージを決定するために評価されます。

現在、サポートされている値は `$request.basepath` のみです。

## WebSocket 選択式の概要
<a name="apigateway-websocket-api-selection-expression-table"></a>

次の表は、WebSocket API の選択式のユースケースをまとめたものです。


| 選択式 | 評価結果のキー | コメント | ユースケースの例 | 
| --- | --- | --- | --- | 
| Api.RouteSelectionExpression | Route.RouteKey | \$1default はキャッチオールルートとしてサポートされています。 | クライアントリクエストのコンテキストに基づいて Route WebSocket メッセージをルーティングします。 | 
| Route.ModelSelectionExpression | Route.RequestModels のキー | オプション。 非プロキシ統合に対して指定されている場合、モデル検証が発生します。 `$default` はキャッチオールとしてサポートされています。  | 同じルート内で動的にリクエスト検証を実行します。 | 
| Integration.TemplateSelectionExpression | Integration.RequestTemplates のキー |  オプション。 受信ペイロードを操作するための非プロキシ統合に提供できます。 `${request.body.jsonPath}` および静的な値がサポートされています。 `$default` はキャッチオールとしてサポートされています。  | リクエストの動的プロパティに基づいて、呼び出し元のリクエストを操作します。 | 
| Integration.IntegrationResponseSelectionExpression | IntegrationResponse.IntegrationResponseKey |  オプション。非プロキシ統合に提供される場合があります。 エラーメッセージのパターン一致 (Lambda から) またはステータスコード (HTTP 統合から) として動作します。 `$default` は、成功したレスポンスのキャッチオールとして動作する非プロキシ統合で必要です。  |  バックエンドからのレスポンスを操作します。 バックエンドの動的なレスポンスに基づいて発生するアクションを選択します (特定のエラーを明確に処理)。  | 
| IntegrationResponse.TemplateSelectionExpression | IntegrationResponse.ResponseTemplates のキー | オプション。非プロキシ統合に提供される場合があります。\$1default はサポートされています。  |  場合によっては、レスポンスの動的プロパティは、同じルートおよび関連する統合内で別の変換を指示します。 `${request.body.jsonPath}`、`${integration.response.statuscode}`、`${integration.response.header.headerName}`、`${integration.response.multivalueheader.headerName}`、および静的な値がサポートされています。 `$default` はキャッチオールとしてサポートされています。  | 
| Route.RouteResponseSelectionExpression | RouteResponse.RouteResponseKey |  WebSocket ルートの双方向通信を開始するために提供する必要があります。 現在、この値は `$default` のみに制限されています。  |  | 
| RouteResponse.ModelSelectionExpression | RouteResponse.RequestModels のキー | 現在サポートされていません。 |  | 

# API Gateway で WebSocket API を開発する
<a name="websocket-api-develop"></a>

このセクションでは、API Gateway API の開発中に必要な API Gateway 機能について詳しく説明します。

API Gateway API の開発中、API の特性をいくつか決定することになります。これらの特性は API のユースケースによって異なります。たとえば、API を特定のクライアントのみが呼び出せるようにしたり、すべてのユーザーが利用できるようにしたりできます。API コールで Lambda 関数の実行、データベースクエリの作成やアプリケーションの呼び出しができます。

**Topics**
+ [API Gateway で WebSocket API を作成する](apigateway-websocket-api-create-empty-api.md)
+ [API Gateway の WebSocket API の IP アドレスタイプ](websocket-api-ip-address-type.md)
+ [API Gateway で WebSocket API のルートを作成する](websocket-api-develop-routes.md)
+ [API Gateway で WebSocket API へのアクセスを制御および管理する](apigateway-websocket-api-control-access.md)
+ [API Gateway での WebSocket API の統合](apigateway-websocket-api-integrations.md)
+ [API Gateway での WebSocket API のリクエスト検証](websocket-api-request-validation.md)
+ [API Gateway での WebSocket API のデータ変換](websocket-api-data-transformations.md)
+ [API Gateway での WebSocket API のバイナリメディアタイプ](websocket-api-develop-binary-media-types.md)
+ [WebSocket API を呼び出す](apigateway-how-to-call-websocket-api.md)

# API Gateway で WebSocket API を作成する
<a name="apigateway-websocket-api-create-empty-api"></a>

WebSocket API は、API Gateway コンソールで AWS CLI [create-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api.html) コマンドを使用するか、AWS SDK で `CreateApi` コマンドを使用して作成できます。以下の手順では、新しい WebSocket API を作成する方法を示しています。

**注記**  
WebSocket API は、TLS 1.2 と TLS 1.3 のみをサポートしています。以前の TLS バージョンはサポートされていません。

## AWS CLI コマンドを使用して WebSocket API を作成する
<a name="apigateway-websocket-api-create-using-awscli"></a>

次の [create-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api.html) コマンドは、`$request.body.action` ルート選択式を含む API を作成します。

```
aws apigatewayv2 --region us-east-1 create-api --name "myWebSocketApi3" --protocol-type WEBSOCKET --route-selection-expression '$request.body.action'
```

出力は次のようになります。

```
{
    "ApiKeySelectionExpression": "$request.header.x-api-key",
    "Name": "myWebSocketApi3",
    "CreatedDate": "2018-11-15T06:23:51Z",
    "ProtocolType": "WEBSOCKET",
    "RouteSelectionExpression": "'$request.body.action'",
    "ApiId": "aabbccddee"
}
```

## API Gateway コンソールを使用した WebSocket API の作成
<a name="apigateway-websocket-api-create-using-console"></a>

WebSocket プロトコルを選択し、API に名前を付けることで、コンソールで WebSocket API を作成できます。

**重要**  
API を作成した後で、選択したプロトコルを変更することはできません。WebSocket API を REST API に変換することはできません。その逆も同様です。

**API Gateway コンソールを使用して WebSocket API を作成するには**

1. API Gateway コンソールにサインインし、[**Create API (API の作成)**] を選択します。

1. [**WebSocket API**] で [**Build (ビルド)**] を選択します リージョンのエンドポイントのみがサポートされます。

1. **[API 名]** に API の名前を入力します。

1. **[ルート選択式]** に値を入力します。例えば、`$request.body.action` と指定します。

   ルート選択式の詳細については、「[ルート選択式](websocket-api-develop-routes.md#apigateway-websocket-api-route-selection-expressions)」を参照してください。

1. 次のいずれかを行ってください。
   + ルートのない API を作成するには、**[空の API を作成]** を選択します。
   + **[次へ]** を選択して API にルートをアタッチします。

   API を作成したら、ルートをアタッチできます。

# API Gateway の WebSocket API の IP アドレスタイプ
<a name="websocket-api-ip-address-type"></a>

API を作成する際、API を呼び出すことができる IP アドレスのタイプを指定します。IPv4 を選択して IPv4 アドレスを解決し、API を呼び出すことができます。デュアルスタックを選択すると、API の呼び出しを IPv4 アドレスと IPv6 アドレスの両方に許可できます。IP アドレスタイプをデュアルスタックに設定して、IP スペースの枯渇の問題を軽減したり、セキュリティ体制を強化したりすることをお勧めします。デュアルスタック IP アドレスタイプの利点の詳細については、「[IPv6 on AWS](https://docs.aws.amazon.com/whitepapers/latest/ipv6-on-aws/internet-protocol-version-6.html)」を参照してください。

## IP アドレスタイプに関する考慮事項
<a name="websocket-api-ip-address-type-considerations"></a>

以下の考慮事項は、IP アドレスタイプの使用に影響する可能性があります。
+ すべての WebSocket API のデフォルトの IP アドレスタイプは IPv4 です。
+ 既存の API の IP アドレスタイプを IPv4 からデュアルスタックに変更する場合、API へのアクセスを制御するポリシーが IPv6 呼び出しを考慮して更新されていることを確認します。IP アドレスタイプを変更すると、変更はすぐに有効になります。
+ API は、その API とは異なる IP アドレスタイプのカスタムドメイン名にマッピングできます。デフォルトの API エンドポイントを無効にすると、発信者が API を呼び出す方法が影響を受ける可能性があります。

## WebSocket API の IP アドレスタイプを変更する
<a name="websocket-api-ip-address-type-change"></a>

IP アドレスタイプは、API の設定を更新して、変更できます。API の設定は、AWS マネジメントコンソール、AWS CLI、CloudFormation、または AWS SDK を使用して、更新できます。API の IP アドレスタイプを変更した場合、API を再デプロイしなくても変更が有効になります。

------
#### [ AWS マネジメントコンソール ]

**WebSocket API の IP アドレスタイプを変更するには**

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

1. WebSocket API を選択します。

1. **[API の設定]**、**[Edit]** の順に選択します。

1. [IP アドレスタイプ] で、**[IPv4]** または **[デュアルスタック]** を選択します。

1. **[保存]** を選択します。

   API の設定の変更はすぐに有効になります。

------
#### [ AWS CLI ]

次の [update-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-api.html) コマンドは、IP アドレスタイプがデュアルスタックになるように API を更新します。

```
aws apigatewayv2 update-api \
    --api-id abcd1234 \
    --ip-address-type dualstack
```

出力は次のようになります。

```
{
    "ApiEndpoint": "https://abcd1234.execute-api.us-east-1.amazonaws.com",
    "ApiId": "abcd1234",
    "ApiKeySelectionExpression": "$request.header.x-api-key",
    "CreatedDate": "2025-02-04T22:20:20+00:00",
    "DisableExecuteApiEndpoint": false,
    "Name": "My-WebSocket-API",
    "ProtocolType": "WEBSOCKET",
    "RouteSelectionExpression": "$request.method $request.path",
    "Tags": {},
    "NotificationUris": [],
    "IpAddressType": "dualstack"
}
```

------

# API Gateway で WebSocket API のルートを作成する
<a name="websocket-api-develop-routes"></a>

WebSocket API では、受信する JSON メッセージは設定したルートに基づいてバックエンド統合に転送されます (JSON 以外のメッセージは、設定した `$default` ルートに転送されます)。

*ルート*には*ルートキー*が含まれます。これは、*ルート選択式*が評価されたときに予期される値です。属性 `routeSelectionExpression` は、API レベルで定義されます。メッセージペイロードに存在することが予期される JSON プロパティを指定します。ルート選択式の詳細については、「[ルート選択式](#apigateway-websocket-api-route-selection-expressions)」を参照してください。

たとえば、JSON メッセージに `action` プロパティが含まれていて、このプロパティに基づいてさまざまなアクションを実行する場合、ルート選択式は `${request.body.action}` のようになります。ルーティングテーブルでは、このテーブルで定義したカスタムルートキーの値に対して、`action` プロパティの値を一致させることによって、実行するアクションを指定します。

3 つの事前定義されたルート (`$connect`、`$disconnect`、および `$default`) を使用できます。さらに、カスタムルートを作成することができます。
+ API Gateway は、クライアントと WebSocket API 間の永続的な接続が開始されたときに、`$connect` ルートを呼び出します。
+ API Gateway は、クライアントまたはサーバーが API から切断したときに、`$disconnect` ルートを呼び出します。
+ API Gateway は、一致するルートが見つかった場合、メッセージに対してルート選択式が評価された後でカスタムルートを呼び出します。この一致により、呼び出される統合が決まります。
+ ルート選択式をメッセージに対して評価できない場合や、一致するルートが見つからない場合、API Gateway は `$default` ルートを呼び出します。

## ルート選択式
<a name="apigateway-websocket-api-route-selection-expressions"></a>

*ルート選択式*は、サービスが受信メッセージについてたどるルートを選択するときに評価されます。このサービスでは、`routeKey` が評価された値に完全に一致するときにルートが使用されます。何も一致せず、`$default` ルートキーを持つルートが存在する場合は、そのルートが選択されます。評価された値と一致するルートがなく、`$default` ルートもない場合、サービスからエラーが返されます。WebSocket ベースの API の場合、式の形式は `$request.body.{path_to_body_element}` である必要があります。

たとえば、次の JSON メッセージを送信するとします。

```
{
    "service" : "chat",
    "action" : "join",
    "data" : {
        "room" : "room1234"
   }
}
```

`action` プロパティに基づいて、API の動作を選択する必要があります。その場合は、次のルート選択式を定義できます。

```
$request.body.action
```

この例で `request.body` は、メッセージの JSON ペイロードを参照し、`.action` が [JSONPath](https://goessner.net/articles/JsonPath/) 式になります。JSON パス式は `request.body` の後に使用できますが、結果は文字列化されることに注意してください。たとえば、JSONPath 式は 2 つの要素の配列を返し、文字列 `"[item1, item2]"` として表示されます。このため、式は配列やオブジェクトではなく値に対して評価することをお勧めします。

静的な値を使用するか、複数の変数を使用できます。以下の表に示しているのは、例と上記のペイロードに対して評価された結果です。


| 式 | 評価結果 | 説明 | 
| --- | --- | --- | 
| \$1request.body.action | join | 1 つのラップ解除された変数 | 
| \$1\$1request.body.action\$1 | join | 1 つのラップされた変数 | 
| \$1\$1request.body.service\$1/\$1\$1request.body.action\$1 | chat/join | 静的な値を持つ複数の変数 | 
| \$1\$1request.body.action\$1-\$1\$1request.body.invalidPath\$1  | join- | JSONPath が見つからない場合、変数は "" として解決されます。 | 
| action | action | 静的な値 | 
| \$1\$1default | \$1default | 静的な値 | 

評価された結果は、ルートを見つけるために使用されます。一致するルートキーがあるルートがある場合、そのルートがメッセージを処理するために選択されます。一致するルートが見つからなかった場合、API Gateway は `$default` ルートを見つけようとします (利用可能な場合)。`$default` ルートが定義されていない場合、API Gateway はエラーを返します。

## API Gateway で WebSocket API のルートを設定する
<a name="apigateway-websocket-api-routes"></a>

新しい WebSocket API を初めて作成するときは、3 つの事前定義されたルート (`$connect`、`$disconnect`、`$default`) があります。これらのルートは、コンソール、API、または AWS CLI を使って作成できます。必要に応じて、カスタムルートを作成することができます。詳細については、「[API Gateway での WebSocket API の概要](apigateway-websocket-api-overview.md)」を参照してください。

**注記**  
CLI では、統合を作成する前または後にルートを作成したり、複数のルートで同じ統合を再利用したりできます。

### API Gateway コンソールを使用したルートの作成
<a name="apigateway-websocket-api-route-using-console"></a>

**API Gateway コンソールを使用してルートを作成するには**

1. API Gateway コンソールにサインインし、[API]、[**Routes (ルート)**] の順に選択します。

1. **[ルートの作成]** を選択します。

1. **[ルートキー]** に、ルートキー名を入力します。定義済みのルート (`$connect`、`$disconnect`、および`$default`) またはカスタムルートを作成できます。
**注記**  
カスタムルートを作成する場合、ルートキー名に `$` プレフィックスは使用しないでください。このプレフィックスは事前定義されたルートのために予約されています。

1. ルートの統合タイプを選択して設定します。詳細については、「[API Gateway コンソールを使用して WebSocket API 統合リクエストを設定する](apigateway-websocket-api-integration-requests.md#apigateway-websocket-api-integration-request-using-console)」を参照してください。

### AWS CLI を使用したルートの作成
<a name="apigateway-websocket-api-route-using-awscli"></a>

次の [create-route](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-route.html) コマンドは、ルートを作成します。

```
aws apigatewayv2 --region us-east-1 create-route --api-id aabbccddee --route-key $default
```

出力は次のようになります。

```
{
    "ApiKeyRequired": false,
    "AuthorizationType": "NONE",
    "RouteKey": "$default",
    "RouteId": "1122334"
}
```

### `$connect` のルートリクエスト設定の指定
<a name="apigateway-websocket-api-route-request-connect"></a>

API の `$connect` ルートを設定するときは、以下のオプション設定を使用して、API の認可を有効にできます。詳細については、「[`$connect` ルート](apigateway-websocket-api-route-keys-connect-disconnect.md#apigateway-websocket-api-routes-about-connect)」を参照してください。
+ **認可**: 認可が必要ない場合は、`NONE`を指定できます。それ以外の場合は、以下を指定できます。
  + API へのアクセスを制御するために標準の AWS IAM ポリシーを使用するには、`AWS_IAM` を指定します。
  + 以前に作成した Lambda オーソライザー関数を指定して API の認可を実装するには、`CUSTOM` を指定します。オーソライザーは、独自の AWS アカウントまたは別の AWS アカウントに設定できます。Lambda オーソライザーの詳細については、「[API Gateway Lambda オーソライザーを使用する](apigateway-use-lambda-authorizer.md)」を参照してください。
**注記**  
API Gateway コンソールで、`CUSTOM` 設定は「[Lambda オーソライザーを設定する (コンソール)](configure-api-gateway-lambda-authorization.md#configure-api-gateway-lambda-authorization-with-console)」で説明したオーソライザー関数を設定した後でのみ表示されます。
**重要**  
**[認可]** 設定は、`$connect` ルートだけではなく、API 全体に適用されます。`$connect` ルートは、すべての接続で呼び出されるため、他のルートを保護します。
+ **API キーの必要性**: 必要に応じて、API の `$connect` ルートで API キーを必須にすることができます。API キーを使用量プランと一緒に使用して、API へのアクセスを制御、追跡できます。詳細については、「[API Gateway での REST API の使用量プランと API キー](api-gateway-api-usage-plans.md)」を参照してください。

### API Gateway コンソールを使用して `$connect` ルートリクエストをセットアップする
<a name="apigateway-websocket-api-connect-route-request-using-console"></a>

API Gateway コンソールを使用して WebSocket API の `$connect` ルートリクエストを設定するには

1. API Gateway コンソールにサインインし、[API]、[**Routes (ルート)**] の順に選択します。

1. **[ルート]** で、`$connect` を選択するか、[API Gateway コンソールを使用したルートの作成](#apigateway-websocket-api-route-using-console) に従って `$connect` ルートを作成します。

1. **[ルートリクエスト設定]** セクションで、**[編集]** を選択します。

1. **[認可]** では、認可タイプを選択します。

1. `$connect` ルートで API キーを必須にするには、**[API キーを必須化]** を選択します。

1. **[Save changes]** (変更の保存) をクリックします。

# API Gateway で WebSocket API のルートレスポンスを設定する
<a name="apigateway-websocket-api-route-response"></a>

WebSocket ルートは、双方向または単方向通信に対して設定できます。ユーザーがルートレスポンスを設定しない限り、API Gateway はルートレスポンスにバックエンドレスポンスを渡しません。

**注記**  
WebSocket API の `$default` ルートレスポンスのみを定義できます。統合レスポンスを使用して、バックエンドサービスからのレスポンスを操作できます。詳細については、「[統合レスポンスの概要](apigateway-websocket-api-integration-responses.md#apigateway-websocket-api-integration-response-overview)」を参照してください。

API Gateway コンソール、AWS CLI、または AWS SDK を使用して、ルートレスポンスとレスポンス選択式を設定できます。

ルートレスポンス選択式の設定の詳細については、「[ルートレスポンス選択式](apigateway-websocket-api-selection-expressions.md#apigateway-websocket-api-route-response-selection-expressions)」を参照してください。

**Topics**
+ [API Gateway コンソールを使用したルートレスポンスの設定](#apigateway-websocket-api-route-response-using-console)
+ [AWS CLI を使用してルートレスポンスを設定する](#apigateway-websocket-api-route-response-using-awscli)

## API Gateway コンソールを使用したルートレスポンスの設定
<a name="apigateway-websocket-api-route-response-using-console"></a>

WebSocket API を作成し、プロキシ Lambda 関数をデフォルトルートにアタッチしたら、API Gateway コンソールを使用してルートレスポンスを設定できます。

1. API Gateway コンソールにサインインし、`$default` ルートの Lambda 関数の統合で WebSocket API を選択します。

1. **[Routes]** (ルート) で、`$default` ルートを選択します。

1. **[双方向通信を有効にする]** を選択します。

1. [**API のデプロイ**] を選択します。

1. API をステージにデプロイします。

 以下の [wscat](https://www.npmjs.com/package/wscat) コマンドを使用して、API に接続します。`wscat` の詳細については、「[`wscat` を使用した WebSocket API への接続とメッセージの送信](apigateway-how-to-call-websocket-api-wscat.md)」を参照してください。

```
wscat -c wss://api-id.execute-api.us-east-2.amazonaws.com/test
```

 Enter ボタンを押して、デフォルトルートを呼び出します。Lambda 関数の本体が戻るはずです。

## AWS CLI を使用してルートレスポンスを設定する
<a name="apigateway-websocket-api-route-response-using-awscli"></a>

次の [create-route-response](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-route-response.html) コマンドは、`$default` ルートのルートレスポンスを作成します。API ID とルート ID は、[get-apis](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/get-apis.html) コマンドと [get-routes](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/get-routes.html) コマンドを使用して特定できます。

```
aws apigatewayv2 create-route-response \
    --api-id aabbccddee \
    --route-id 1122334  \
    --route-response-key '$default'
```

出力は次のようになります。

```
{
    "RouteResponseId": "abcdef",
    "RouteResponseKey": "$default"
}
```

# WebSocket サブプロトコルを必要とする `$connect` ルートを設定する
<a name="websocket-connect-route-subprotocol"></a>

クライアントは、WebSocket API への接続中に、`Sec-WebSocket-Protocol` フィールドを使用して [WebSocket サブプロトコル](https://datatracker.ietf.org/doc/html/rfc6455#page-12)をリクエストできます。API がサポートするサブプロトコルをクライアントがリクエストした場合にのみ接続を許可するように、`$connect` ルートの統合を設定できます。

次の Lambda 関数の例は、`Sec-WebSocket-Protocol` ヘッダーをクライアントに返します。この関数は、クライアントが `myprotocol` サブプロトコルを指定した場合のみ API への接続を確立します。

このサンプル API と Lambda プロキシ統合を作成する CloudFormation テンプレートについては、[samples/ws-subprotocol.zip](samples/ws-subprotocol.zip) を参照してください。

```
export const handler = async (event) => {
    if (event.headers != undefined) {
        const headers = toLowerCaseProperties(event.headers);
        
        if (headers['sec-websocket-protocol'] != undefined) {
            const subprotocolHeader = headers['sec-websocket-protocol'];
            const subprotocols = subprotocolHeader.split(',');
            
            if (subprotocols.indexOf('myprotocol') >= 0) {
                const response = {
                    statusCode: 200,
                    headers: {
                        "Sec-WebSocket-Protocol" : "myprotocol"
                    }
                };
                return response;
            }
        }
    }
    
    const response = {
        statusCode: 400
    };
        
    return response;
};

function toLowerCaseProperties(obj) {
    var wrapper = {};
    for (var key in obj) {
        wrapper[key.toLowerCase()] = obj[key];
    }
    return wrapper;
}
```

[https://www.npmjs.com/package/wscat](https://www.npmjs.com/package/wscat) を使用して、API がサポートするサブプロトコルをクライアントがリクエストした場合にのみ API が接続を許可することをテストできます。次のコマンドは、`-s` フラグを使用して、接続中にサブプロトコルを指定します。

次のコマンドは、サポートされていないサブプロトコルとの接続を試行します。クライアントが `chat1` サブプロトコルを指定したため、Lambda 統合は 400 エラーを返し、接続は失敗します。

```
wscat -c wss://api-id.execute-api.region.amazonaws.com/beta -s chat1
error: Unexpected server response: 400
```

次のコマンドは、サポートされているサブプロトコルを接続リクエストに含めます。Lambda 統合により、接続が可能になります。

```
wscat -c wss://api-id.execute-api.region.amazonaws.com/beta -s chat1,myprotocol
connected (press CTRL+C to quit)
```

WebSocket API の呼び出しの詳細については、「[WebSocket API を呼び出す](apigateway-how-to-call-websocket-api.md)」を参照してください。

# API Gateway で WebSocket API へのアクセスを制御および管理する
<a name="apigateway-websocket-api-control-access"></a>

API Gateway は、WebSocket API へのアクセスを制御および管理するための複数のメカニズムをサポートしています。

認証と認可に次のメカニズムを使用することができます。
+ **標準の AWS IAM ロールとポリシー**は、柔軟で堅牢なアクセス制御を提供します。IAM ロールとポリシーを使用して、API を作成および管理できるユーザーと、API を呼び出すことができるユーザーを制御できます。詳細については、「[IAM 認可を使用して WebSocket API へのアクセスを制御する](apigateway-websocket-control-access-iam.md)」を参照してください。
+ **IAM タグ**は、アクセスをコントロールするために、IAM ポリシーと共に使用できます。詳細については、「[タグを使用して API Gateway REST API リソースへのアクセスをコントロールする](apigateway-tagging-iam-policy.md)」を参照してください。
+ **Lambda オーソライザー** は、API へのアクセスを制御する Lambda 関数です。詳細については、「[AWS Lambda REQUEST オーソライザーを使用して WebSocket API へのアクセスを制御する](apigateway-websocket-api-lambda-auth.md)」を参照してください。

セキュリティ体制を向上させるには、すべての WebSocket API で `$connect` ルートのオーソライザーを設定することをお勧めします。これは、さまざまなコンプライアンスフレームワークに準拠するために必要になる場合があります。詳細については、*AWS Security Hub ユーザーガイド*の「[Amazon API Gateway のコントロール](https://docs.aws.amazon.com/securityhub/latest/userguide/apigateway-controls.html)」を参照してください。

**Topics**
+ [IAM 認可を使用して WebSocket API へのアクセスを制御する](apigateway-websocket-control-access-iam.md)
+ [AWS Lambda REQUEST オーソライザーを使用して WebSocket API へのアクセスを制御する](apigateway-websocket-api-lambda-auth.md)

# IAM 認可を使用して WebSocket API へのアクセスを制御する
<a name="apigateway-websocket-control-access-iam"></a>

WebSocket API の IAM 認可は [REST API](api-gateway-control-access-using-iam-policies-to-invoke-api.md) と似ていますが、次のような例外があります。
+ 既存のアクション (`execute-api`、`ManageConnections`) に加えて、`Invoke` アクションは `InvalidateCache` をサポートしています。`ManageConnections` は @connections API へのアクセスを制御します。
+ WebSocket ルートは別の ARN 形式を使用します。

  ```
  arn:aws:execute-api:region:account-id:api-id/stage-name/route-key
  ```
+ この `@connections` API は、REST API と同じ ARN 形式を使用します。

  ```
  arn:aws:execute-api:region:account-id:api-id/stage-name/POST/@connections
  ```

**重要**  
[IAM 認可](#apigateway-websocket-control-access-iam)を使用する場合は、[Signature Version 4 (SigV4)](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html) でリクエストに署名する必要があります。

たとえば、クライアントに次のポリシーを設定できます。次の例では、全員がメッセージ (`Invoke`) を `prod` ステージのシークレットルートを除くすべてのルートに送信でき、全員がすべてのステージの接続されたクライアント (`ManageConnections`) にメッセージを送信するのを防ぎます。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "execute-api:Invoke"
            ],
            "Resource": [
                "arn:aws:execute-api:us-east-1:111122223333:api-id/prod/*"
            ]
        },
        {
            "Effect": "Deny",
            "Action": [
                "execute-api:Invoke"
            ],
            "Resource": [
                "arn:aws:execute-api:us-east-1:111122223333:api-id/prod/secret"
            ]
        },
        {
            "Effect": "Deny",
            "Action": [
                "execute-api:ManageConnections"
            ],
            "Resource": [
                "arn:aws:execute-api:us-east-1:111122223333:api-id/*"
            ]
        }
    ]
}
```

------

# AWS Lambda REQUEST オーソライザーを使用して WebSocket API へのアクセスを制御する
<a name="apigateway-websocket-api-lambda-auth"></a>

WebSocket API の Lambda オーソライザー関数は、[REST API](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-lambda-function-create) と似ていますが、次のような例外があります。
+  Lambda オーソライザー関数は、`$connect` ルートにのみ使用できます。
+ パス変数 (`event.pathParameters`) を使用することはできません。これは、パスが固定されているためです。
+ `event.methodArn` は、HTTP メソッドがないため、REST API の同等のメソッドとは異なります。`$connect` の場合、`methodArn` は `"$connect"` で終了します。

  ```
  arn:aws:execute-api:region:account-id:api-id/stage-name/$connect
  ```
+ `event.requestContext` のコンテキスト変数は、REST API のコンテキスト変数とは異なります。

 次の例では、WebSocket API の `REQUEST` オーソライザーへの入力を示しています。

```
{
    "type": "REQUEST",
    "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/default/$connect",
    "headers": {
        "Connection": "upgrade",
        "content-length": "0",
        "HeaderAuth1": "headerValue1",
        "Host": "abcdef123.execute-api.us-east-1.amazonaws.com",
        "Sec-WebSocket-Extensions": "permessage-deflate; client_max_window_bits",
        "Sec-WebSocket-Key": "...",
        "Sec-WebSocket-Version": "13",
        "Upgrade": "websocket",
        "X-Amzn-Trace-Id": "...",
        "X-Forwarded-For": "...",
        "X-Forwarded-Port": "443",
        "X-Forwarded-Proto": "https"
    },
    "multiValueHeaders": {
        "Connection": [
            "upgrade"
        ],
        "content-length": [
            "0"
        ],
        "HeaderAuth1": [
            "headerValue1"
        ],
        "Host": [
            "abcdef123.execute-api.us-east-1.amazonaws.com"
        ],
        "Sec-WebSocket-Extensions": [
            "permessage-deflate; client_max_window_bits"
        ],
        "Sec-WebSocket-Key": [
            "..."
        ],
        "Sec-WebSocket-Version": [
            "13"
        ],
        "Upgrade": [
            "websocket"
        ],
        "X-Amzn-Trace-Id": [
            "..."
        ],
        "X-Forwarded-For": [
            "..."
        ],
        "X-Forwarded-Port": [
            "443"
        ],
        "X-Forwarded-Proto": [
            "https"
        ]
    },
    "queryStringParameters": {
        "QueryString1": "queryValue1"
    },
    "multiValueQueryStringParameters": {
        "QueryString1": [
            "queryValue1"
        ]
    },
    "stageVariables": {},
    "requestContext": {
        "routeKey": "$connect",
        "eventType": "CONNECT",
        "extendedRequestId": "...",
        "requestTime": "19/Jan/2023:21:13:26 +0000",
        "messageDirection": "IN",
        "stage": "default",
        "connectedAt": 1674162806344,
        "requestTimeEpoch": 1674162806345,
        "identity": {
            "sourceIp": "..."
        },
        "requestId": "...",
        "domainName": "abcdef123.execute-api.us-east-1.amazonaws.com",
        "connectionId": "...",
        "apiId": "abcdef123"
    }
}
```

次の例では、Lambda オーソライザー関数は、[その他の Lambda オーソライザー関数の例](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-lambda-function-create) の REST API の Lambda オーソライザー関数の WebSocket バージョンです。

------
#### [ Node.js ]

```
   // A simple REQUEST authorizer example to demonstrate how to use request 
   // parameters to allow or deny a request. In this example, a request is  
   // authorized if the client-supplied HeaderAuth1 header and QueryString1 query parameter
   // in the request context match the specified values of
   // of 'headerValue1' and 'queryValue1' respectively.
            export const handler = function(event, context, callback) {
    console.log('Received event:', JSON.stringify(event, null, 2));

   // Retrieve request parameters from the Lambda function input:
   var headers = event.headers;
   var queryStringParameters = event.queryStringParameters;
   var stageVariables = event.stageVariables;
   var requestContext = event.requestContext;
       
   // Parse the input for the parameter values
   var tmp = event.methodArn.split(':');
   var apiGatewayArnTmp = tmp[5].split('/');
   var awsAccountId = tmp[4];
   var region = tmp[3];
   var ApiId = apiGatewayArnTmp[0];
   var stage = apiGatewayArnTmp[1];
   var route = apiGatewayArnTmp[2];
       
   // Perform authorization to return the Allow policy for correct parameters and 
   // the 'Unauthorized' error, otherwise.
   var authResponse = {};
   var condition = {};
    condition.IpAddress = {};
    
   if (headers.HeaderAuth1 === "headerValue1"
       && queryStringParameters.QueryString1 === "queryValue1") {
        callback(null, generateAllow('me', event.methodArn));
    }  else {
        callback(null, generateDeny('me', event.methodArn)); 
    }
}
    
// Helper function to generate an IAM policy
var generatePolicy = function(principalId, effect, resource) {
   // Required output:
   var authResponse = {};
    authResponse.principalId = principalId;
   if (effect && resource) {
       var policyDocument = {};
        policyDocument.Version = '2012-10-17		 	 	 '; // default version
       policyDocument.Statement = [];
       var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; // default action
       statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
   // Optional output with custom properties of the String, Number or Boolean type.
   authResponse.context = {
       "stringKey": "stringval",
       "numberKey": 123,
       "booleanKey": true
    };
   return authResponse;
}
    
var generateAllow = function(principalId, resource) {
   return generatePolicy(principalId, 'Allow', resource);
}
    
var generateDeny = function(principalId, resource) {
   return generatePolicy(principalId, 'Deny', resource);
}
```

------
#### [ Python ]

```
# A simple REQUEST authorizer example to demonstrate how to use request
# parameters to allow or deny a request. In this example, a request is
# authorized if the client-supplied HeaderAuth1 header and QueryString1 query parameter
# in the request context match the specified values of
# of 'headerValue1' and 'queryValue1' respectively.

import json


def lambda_handler(event, context):
    print(event)

    # Retrieve request parameters from the Lambda function input:
    headers = event['headers']
    queryStringParameters = event['queryStringParameters']
    stageVariables = event['stageVariables']
    requestContext = event['requestContext']

    # Parse the input for the parameter values
    tmp = event['methodArn'].split(':')
    apiGatewayArnTmp = tmp[5].split('/')
    awsAccountId = tmp[4]
    region = tmp[3]
    ApiId = apiGatewayArnTmp[0]
    stage = apiGatewayArnTmp[1]
    route = apiGatewayArnTmp[2]

    # Perform authorization to return the Allow policy for correct parameters
    # and the 'Unauthorized' error, otherwise.

    authResponse = {}
    condition = {}
    condition['IpAddress'] = {}

    if (headers['HeaderAuth1'] ==
            "headerValue1" and queryStringParameters["QueryString1"] == "queryValue1"):
        response = generateAllow('me', event['methodArn'])
        print('authorized')
        return json.loads(response)
    else:
        response = generateDeny('me', event['methodArn'])
        print('unauthorized')
        return json.loads(response)

    # Help function to generate IAM policy


def generatePolicy(principalId, effect, resource):
    authResponse = {}
    authResponse['principalId'] = principalId
    if (effect and resource):
        policyDocument = {}
        policyDocument['Version'] = '2012-10-17		 	 	 '
        policyDocument['Statement'] = []
        statementOne = {}
        statementOne['Action'] = 'execute-api:Invoke'
        statementOne['Effect'] = effect
        statementOne['Resource'] = resource
        policyDocument['Statement'] = [statementOne]
        authResponse['policyDocument'] = policyDocument

    authResponse['context'] = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": True
    }

    authResponse_JSON = json.dumps(authResponse)

    return authResponse_JSON


def generateAllow(principalId, resource):
    return generatePolicy(principalId, 'Allow', resource)


def generateDeny(principalId, resource):
    return generatePolicy(principalId, 'Deny', resource)
```

------

前述の Lambda 関数を WebSocket API の `REQUEST` オーソライザー関数として設定する場合、[REST API](configure-api-gateway-lambda-authorization.md#configure-api-gateway-lambda-authorization-with-console) と同じ手順に従います。

コンソールでこの Lambda オーソライザーを使用するよう `$connect` ルートを設定するには、`$connect` ルートを選択または作成します。**[ルートリクエスト設定]** セクションで、**[編集]** を選択します。**[承認]** ドロップダウンメニューで承認者を選択し、**[変更を保存]** を選択します。

オーソライザーをテストするには、新しい接続を作成する必要があります。`$connect` でオーソライザーを変更しても、接続済みのクライアントに影響はありません。WebSocket API に接続するときは、設定済みの ID ソースの値を指定する必要があります。たとえば、次の例のように `wscat` を使用し、有効なクエリ文字列およびヘッダーを送信して接続できます。

```
wscat -c 'wss://myapi.execute-api.us-east-1.amazonaws.com/beta?QueryString1=queryValue1' -H HeaderAuth1:headerValue1
```

有効な ID 値なしに接続しようとすると、`401` レスポンスが送信されます。

```
wscat -c wss://myapi.execute-api.us-east-1.amazonaws.com/beta
error: Unexpected server response: 401
```

# API Gateway での WebSocket API の統合
<a name="apigateway-websocket-api-integrations"></a>

API ルートを設定したら、バックエンドのエンドポイントに統合する必要があります。バックエンドエンドポイントは、統合エンドポイントとも呼ばれ、Lambda 関数、HTTP エンドポイント、または AWS のサービスアクションにすることができます。API 統合には統合リクエストと統合レスポンスがあります。

このセクションでは、 WebSocket API の統合リクエストと統合レスポンスを設定する方法を説明します。

**Topics**
+ [API Gateway で WebSocket API 統合リクエストを設定する](apigateway-websocket-api-integration-requests.md)
+ [API Gateway で WebSocket API 統合レスポンスを設定する](apigateway-websocket-api-integration-responses.md)

# API Gateway で WebSocket API 統合リクエストを設定する
<a name="apigateway-websocket-api-integration-requests"></a>

統合リクエストの設定では、次の操作が必要になります。
+ バックエンドに統合するルートキーを選択します。
+ 呼び出すバックエンドエンドポイントを指定します。WebSocket API は、以下の統合タイプをサポートしています。
  + `AWS_PROXY`
  + `AWS`
  + `HTTP_PROXY`
  + `HTTP`
  + `MOCK`

  統合タイプの詳細については、API Gateway V2 REST API の [IntegrationType](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid.html#apis-apiid-integrations-integrationid-prop-integration-integrationtype) を参照してください。
+ 必要に応じて、1 つ以上のリクエストテンプレートを指定して、ルートリクエストデータを統合リクエストデータに変換する方法を設定します。

## API Gateway コンソールを使用して WebSocket API 統合リクエストを設定する
<a name="apigateway-websocket-api-integration-request-using-console"></a>

**API Gateway コンソールを使用して統合リクエストを WebSocket API のルートに追加するには**

1. API Gateway コンソールにサインインし、[API]、[**Routes (ルート)**] の順に選択します。

1. [**ルート**] で、ルートを選択します。

1. **[統合リクエスト]** タブを選択し、**[統合リクエスト設定]** セクションで **[編集]** を選択します。

1. **[統合タイプ]** で、以下のいずれかを選択します。
   + **[Lambda 関数]** は、API がこのアカウントまたは別のアカウントで既に作成済みの AWS Lambda 関数と統合される場合のみ選択してください。

     AWS Lambda で新しい Lambda 関数を作成する場合、Lambda 関数にリソースのアクセス許可を設定する場合、またはその他の Lambda サービスアクションを実行する場合、代わりに [**AWS Service**] (AWS のサービス) を選択します。
   + API が既存の HTTP エンドポイントに統合される場合は、[**HTTP**] を選択します。詳細については、「[API Gateway での REST API の HTTP 統合](setup-http-integrations.md)」を参照してください。
   + 統合バックエンドを必要とすることなく、API Gateway から直接 API レスポンスを生成する場合は、[**Mock**] を選択します。詳細については、「[API Gateway での REST API の Mock 統合](how-to-mock-integration.md)」を参照してください。
   + API が AWS のサービスと直接統合する場合は、**[AWS のサービス]** を選択します。
   + API でプライベート統合エンドポイントして `VpcLink` を使用する場合は、**[VPC リンク]** を選択します。詳細については、「[プライベート統合の設定](set-up-private-integration.md)」を参照してください。

1. **[Lambda 関数]** を選択した場合は、以下の操作を実行します。

   1. **[プロキシ統合の使用]** で、[Lambda プロキシ統合](set-up-lambda-proxy-integrations.md#api-gateway-create-api-as-simple-proxy)または[ クロスアカウントの Lambda プロキシ統合](apigateway-cross-account-lambda-integrations.md)を使用する場合は、チェックボックスをオンにします。

   1. **[Lambda 関数]** で、次のいずれかの方法で関数を指定します。
      + Lambda 関数が同じアカウントにある場合、関数名を入力し、表示されたドロップダウンリストから関数を選択します。
**注記**  
関数名には、オプションでエイリアスまたはバージョン指定を含めることができます (`HelloWorld`、`HelloWorld:1`、または `HelloWorld:alpha`)。
      + 関数が別のアカウントにある場合は、関数の ARN を入力します。

   1. 29 秒のデフォルトのタイムアウト値を使用するには、**[デフォルトタイムアウト]** をオンのままにします。カスタムのタイムアウトを設定するには、**[デフォルトタイムアウト]** を選択してから、タイムアウト値を `50` ～ `29000` ミリ秒の間で入力します。

1. [**HTTP**] を選択した場合は、「[API Gateway コンソールを使用して API 統合リクエストを設定する](how-to-method-settings-console.md)」のステップ 4 に従います。

1. [**Mock**] を選択した場合は、[**リクエストテンプレート**] ステップに進みます。

1. **[AWS のサービス]** を選択した場合は、「[API Gateway コンソールを使用して API 統合リクエストを設定する](how-to-method-settings-console.md)」のステップ 6 に従います。

1. **[VPC リンク]** を選択した場合は、以下の操作を実行します。

   1. **[VPC プロキシ統合の使用]** で、リクエストを `VPCLink` のエンドポイントにプロキシする場合は、チェックボックスを選択します。

   1. [**HTTP メソッド**] で、HTTP バックエンドのメソッドに最も厳密に一致する HTTP メソッドタイプを選択します。

   1. **[VPC リンク]** ドロップダウンリストから、[VPC リンク] を選択します。`[Use Stage Variables]` を選択して、リストの下のテキストボックスに **\$1\$1stageVariables.vpcLinkId\$1** を入力できます。

      ステージに API をデプロイした後、`vpcLinkId` ステージ変数を定義し、その値を `VpcLink` の ID に定義できます。

   1. [**エンドポイント URL**] に、この統合で使用する HTTP バックエンドの URL を入力します。

   1. 29 秒のデフォルトのタイムアウト値を使用するには、**[デフォルトタイムアウト]** をオンのままにします。カスタムのタイムアウトを設定するには、**[デフォルトタイムアウト]** を選択してから、タイムアウト値を `50` ～ `29000` ミリ秒の間で入力します。

1. [**Save changes**] (変更の保存) をクリックします。

1. **[クエストテンプレート]** で、次の操作を行います。

   1. **テンプレート選択式**を入力するには、**[リクエストテンプレート]** で **[編集]** を選択します。

   1. **テンプレート選択式**を入力します。メッセージペイロード内で API Gateway が検索する式を使用します。見つかった式は評価され、結果はメッセージペイロード内のデータに適用されるデータのマッピングテンプレートを選択するために使用されるテンプレートキー値となります。次のステップで、データマッピングテンプレートを作成します。**[はい、編集します]** を選択して、変更を保存します。

   1. **[テンプレートの作成]** を選択してデータマッピングテンプレートを作成します。**[テンプレートキー]** に、メッセージペイロード内のデータに適用されるデータマッピングの選択に使用するテンプレートキー値を入力します。次に、マッピングテンプレートを入力します。**[テンプレートを作成]** をクリックします。

      テンプレート選択式の詳細については、「[テンプレート選択式](websocket-api-data-transformations.md#apigateway-websocket-api-template-selection-expressions)」を参照してください。

## AWS CLI を使用して統合リクエストを設定する
<a name="apigateway-websocket-api-integration-request-using-awscli"></a>

WebSocket API のルートの統合リクエストを設定するには、次の例のように、Mock 統合を作成する AWS CLI を使用します。

1. 次の内容で、`integration-params.json` というファイルを作成します。

   ```
   {"PassthroughBehavior": "WHEN_NO_MATCH", "TimeoutInMillis": 29000, "ConnectionType": "INTERNET", "RequestTemplates": {"application/json": "{\"statusCode\":200}"}, "IntegrationType": "MOCK"}
   ```

1. 次の [create-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html) コマンドを使用して、モック統合を作成します。

   ```
   aws apigatewayv2 --region us-east-1 create-integration --api-id aabbccddee --cli-input-json file://integration-params.json
   ```

   出力は次のようになります。

   ```
   {
       "PassthroughBehavior": "WHEN_NO_MATCH",
       "TimeoutInMillis": 29000,
       "ConnectionType": "INTERNET",
       "IntegrationResponseSelectionExpression": "${response.statuscode}",
       "RequestTemplates": {
           "application/json": "{\"statusCode\":200}"
       },
       "IntegrationId": "0abcdef",
       "IntegrationType": "MOCK"
   }
   ```

または、AWS CLI を使用してプロキシ統合の統合リクエストを設定することもできます。

1. Lambda コンソールで Lambda 関数を作成し、基本的な Lambda 実行ロールを提供します。

1. 次の [create-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html) コマンドを使用して、統合を作成します。

   ```
   aws apigatewayv2 create-integration --api-id aabbccddee --integration-type AWS_PROXY --integration-method POST --integration-uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123412341234:function:simpleproxy-echo-e2e/invocations
   ```

出力は次のようになります。

```
{
    "PassthroughBehavior": "WHEN_NO_MATCH",
    "IntegrationMethod": "POST",
    "TimeoutInMillis": 29000,
    "ConnectionType": "INTERNET",
    "IntegrationUri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123412341234:function:simpleproxy-echo-e2e/invocations",
    "IntegrationId": "abcdefg",
    "IntegrationType": "AWS_PROXY"
}
```

## WebSocket API のプロキシ統合のための Lambda 関数の入力形式
<a name="api-gateway-simple-proxy-for-lambda-input-format-websocket"></a>

Lambda プロキシ統合では、API Gateway がクライアントリクエスト全体をバックエンド Lambda 関数の入力 `event` パラメータにマップします。次の例は、API Gateway が Lambda プロキシ統合に送信する `$connect` ルートおよび `$disconnect` ルートの入力イベントの構造を示しています。

------
#### [ Input from the \$1connect route ]

```
{
    headers: {
      Host: 'abcd123.execute-api.us-east-1.amazonaws.com',
      'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits',
      'Sec-WebSocket-Key': '...',
      'Sec-WebSocket-Version': '13',
      'X-Amzn-Trace-Id': '...',
      'X-Forwarded-For': '192.0.2.1',
      'X-Forwarded-Port': '443',
      'X-Forwarded-Proto': 'https'
    },
    multiValueHeaders: {
      Host: [ 'abcd123.execute-api.us-east-1.amazonaws.com' ],
      'Sec-WebSocket-Extensions': [ 'permessage-deflate; client_max_window_bits' ],
      'Sec-WebSocket-Key': [ '...' ],
      'Sec-WebSocket-Version': [ '13' ],
      'X-Amzn-Trace-Id': [ '...' ],
      'X-Forwarded-For': [ '192.0.2.1' ],
      'X-Forwarded-Port': [ '443' ],
      'X-Forwarded-Proto': [ 'https' ]
    },
    requestContext: {
      routeKey: '$connect',
      eventType: 'CONNECT',
      extendedRequestId: 'ABCD1234=',
      requestTime: '09/Feb/2024:18:11:43 +0000',
      messageDirection: 'IN',
      stage: 'prod',
      connectedAt: 1707502303419,
      requestTimeEpoch: 1707502303420,
      identity: { sourceIp: '192.0.2.1' },
      requestId: 'ABCD1234=',
      domainName: 'abcd1234.execute-api.us-east-1.amazonaws.com',
      connectionId: 'AAAA1234=',
      apiId: 'abcd1234'
    },
    isBase64Encoded: false
  }
```

------
#### [ Input from the \$1disconnect route ]

```
{
    headers: {
      Host: 'abcd1234.execute-api.us-east-1.amazonaws.com',
      'x-api-key': '',
      'X-Forwarded-For': '',
      'x-restapi': ''
    },
    multiValueHeaders: {
      Host: [ 'abcd1234.execute-api.us-east-1.amazonaws.com' ],
      'x-api-key': [ '' ],
      'X-Forwarded-For': [ '' ],
      'x-restapi': [ '' ]
    },
    requestContext: {
      routeKey: '$disconnect',
      disconnectStatusCode: 1005,
      eventType: 'DISCONNECT',
      extendedRequestId: 'ABCD1234=',
      requestTime: '09/Feb/2024:18:23:28 +0000',
      messageDirection: 'IN',
      disconnectReason: 'Client-side close frame status not set',
      stage: 'prod',
      connectedAt: 1707503007396,
      requestTimeEpoch: 1707503008941,
      identity: { sourceIp: '192.0.2.1' },
      requestId: 'ABCD1234=',
      domainName: 'abcd1234.execute-api.us-east-1.amazonaws.com',
      connectionId: 'AAAA1234=',
      apiId: 'abcd1234'
    },
    isBase64Encoded: false
  }
```

------

# API Gateway で WebSocket API 統合レスポンスを設定する
<a name="apigateway-websocket-api-integration-responses"></a>

次のセクションでは、WebSocket API の統合レスポンスの概要を示し、WebSocket API の統合レスポンスを設定する方法について説明します。

**Topics**
+ [統合レスポンスの概要](#apigateway-websocket-api-integration-response-overview)
+ [双方向通信の統合レスポンス](#apigateway-websocket-api-integration-response-for-two-way-communication)
+ [API Gateway コンソールを使用した統合レスポンスの設定](#apigateway-websocket-api-integration-response-using-console)
+ [AWS CLI を使用して統合レスポンスを設定する](#apigateway-websocket-api-integration-response-using-awscli)

## 統合レスポンスの概要
<a name="apigateway-websocket-api-integration-response-overview"></a>

API Gateway の統合レスポンスとは、バックエンドサービスからのレスポンスをモデル化および操作するための方法です。REST API と WebSocket API 統合レスポンスの設定にはいくつかの違いがありますが、概念的には同じ動作です。

WebSocket ルートは、双方向または単方向通信に対して設定できます。
+ ルートが双方向通信用に設定されている場合、REST API の統合レスポンスと同様に、統合レスポンスにより、返されたメッセージペイロードで変換を設定できます。
+ ルートが単方向通信用に設定されている場合、統合レスポンスの設定に関係なく、メッセージの処理後に WebSocket チャネル経由でレスポンスは返されません。

 ユーザーがルートレスポンスを設定しない限り、API Gateway はルートレスポンスにバックエンドレスポンスを渡しません。ルートレスポンスの詳しい設定方法については、「[API Gateway で WebSocket API のルートレスポンスを設定する](apigateway-websocket-api-route-response.md)」を参照してください。

## 双方向通信の統合レスポンス
<a name="apigateway-websocket-api-integration-response-for-two-way-communication"></a>

統合は*プロキシ*統合と*非プロキシ*統合に分割することができます。

**重要**  
*プロキシ統合*では、API Gateway は自動的にバックエンド出力を完全なペイロードとして発信者に渡します。統合レスポンスは発生しません。

*非プロキシ統合*の場合、少なくとも 1 つの統合レスポンスを設定する必要があります。
+ 明示的な選択が行われなかった場合、いずれかの統合レスポンスがキャッチオールとして機能することが理想的です。このデフォルトのケースは、統合レスポンスキー `$default` を設定することにより表されます。
+ 他のいずれの場合も、統合レスポンスキーは正規表現として機能します。これは、`"/expression/"` の形式に従う必要があります。

非プロキシ HTTP 統合の場合:
+ API Gateway は、バックエンドレスポンスの HTTP ステータスコードへの一致を試みます。この場合、統合レスポンスキーは正規表現として機能します。一致が見つからない場合、`$default` が統合レスポンスとして選択されます。
+ テンプレート選択式も、前述したように同様に機能します。例:
  + `/2\d\d/`: 成功のレスポンスを受信して変換
  + `/4\d\d/`: 不正なリクエストエラーを受信して変換
  + `$default`: すべての予期しないレスポンスを受信して変換

テンプレート選択式の詳細については、「[テンプレート選択式](websocket-api-data-transformations.md#apigateway-websocket-api-template-selection-expressions)」を参照してください。

## API Gateway コンソールを使用した統合レスポンスの設定
<a name="apigateway-websocket-api-integration-response-using-console"></a>

API Gateway コンソールを使用して WebSocket API のルート統合レスポンスを設定するには

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

1.  WebSocket API を選択し、ルートを選択します。

1. **[統合リクエスト]** タブを選択してから、**[統合リクエスト設定]** セクションで **[統合レスポンスの作成]** を選択します。

1. **[レスポンスキー]** に、レスポンス選択式を評価した後で、送信メッセージのレスポンスキーに表示される値を入力します。たとえば、**/4\$1d\$1d/** を入力して不正なリクエストエラーを受信して変換したり、**\$1default** を入力してテンプレート選択式に一致するすべてのレスポンスを受信して変換したりできます。

1. **[テンプレート選択式]** には、送信メッセージを評価するための選択式を入力します。

1. **[レスポンスの作成]** を選択します。

1. マッピングテンプレートを定義して、返されるメッセージペイロードの変換を設定することもできます。**[テンプレートを作成]** をクリックします。

1. キー名を入力します。デフォルトのテンプレート選択式を選択する場合は、**\$1\$1default** を入力します。

1. **[レスポンステンプレート]** に、コードエディタのマッピングテンプレートを入力します。

1. **[テンプレートを作成]** をクリックします。

1. **[API をデプロイ]** を選択して、API をデプロイします。

 以下の [wscat](https://www.npmjs.com/package/wscat) コマンドを使用して、API に接続します。`wscat` の詳細については、「[`wscat` を使用した WebSocket API への接続とメッセージの送信](apigateway-how-to-call-websocket-api-wscat.md)」を参照してください。

```
wscat -c wss://api-id.execute-api.us-east-2.amazonaws.com/test
```

 ルートを呼び出すと、返されたメッセージペイロードが戻るはずです。

## AWS CLI を使用して統合レスポンスを設定する
<a name="apigateway-websocket-api-integration-response-using-awscli"></a>

次の [create-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration-response.html) コマンドは、`$default` 統合レスポンスを作成します。

```
aws apigatewayv2 create-integration-response \
    --api-id vaz7da96z6 \
    --integration-id a1b2c3 \
    --integration-response-key '$default'
```

# API Gateway での WebSocket API のリクエスト検証
<a name="websocket-api-request-validation"></a>

統合リクエストを進める前にルートリクエストの検証を実行するよう API Gateway を設定できます。検証に失敗すると、API ゲートウェイはバックエンドを呼び出さずにリクエストを失敗させ、「Bad request body」というゲートウェイレスポンスをクライアントに送信し、CloudWatch Logs に検証の失敗を発行します。このように検証を使用すると、APIバックエンドへの不要な呼び出しを減らすことができます。

## モデル選択式
<a name="apigateway-websocket-api-model-selection-expressions"></a>

モデル選択式を使用して、同じルート内のリクエストを動的に検証できます。モデルの検証は、プロキシ統合または非プロキシ統合のモデル選択式を指定した場合に行われます。一致するモデルが見つからない場合は、`$default` モデルをフォールバックとして定義する必要があります。一致するモデルが存在せず、`$default` が定義されていない場合、検証は失敗します。選択式は `Route.ModelSelectionExpression` のような外観で 、`Route.RequestModels` のキーに評価されます。

WebSocket API のルートを定義する場合、オプションで*モデル選択式*を指定できます。この式は評価され、リクエストが受信されたときに本文の検証に使用されるモデルが選択されます。この式はルートの [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-routes.html#apis-apiid-routes-prop-route-requestmodels](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-routes.html#apis-apiid-routes-prop-route-requestmodels) のいずれかのエントリに評価されます。

モデルは [JSON スキーマ](https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04)としてで表され、リクエストボディのデータ構造を説明します。この選択式の特性により、特定のルートに対して実行時に検証するモデルを動的に選択できます。モデルを作成する方法については、「[REST API のデータモデル](models-mappings-models.md)」を参照してください。

## API Gateway コンソールを使用してリクエストの検証を設定する
<a name="apigateway-websocket-api-model-selection-expression-example"></a>

次の例は、ルートにリクエストの検証を設定する方法を示しています。

 最初にモデルを作成し、次にルートを作成します。次に、作成したルートにリクエストの検証を設定します。最後に、API をデプロイしてテストします。このチュートリアルを完了するには、`$request.body.action` をルート選択式とする WebSocket API と、新しいルートの統合エンドポイントが必要です。

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

**モデルを作成するには**

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

1. WebSocket API を選択します。

1. ナビゲーションペインで、**[モデル]** を選択します。

1. **[モデルの作成]** を選択します。

1. **[Name]** (名前) には **emailModel** を入力します。

1. **[コンテンツタイプ]** に、「**application/json**」と入力します。

1. **[モデルのスキーマ]** に次のモデルを入力します。

   ```
   {
       "$schema": "http://json-schema.org/draft-04/schema#",
       "type" : "object",
       "required" : [ "address"],
       "properties" : {
           "address": {
               "type": "string"
           }
       }
   }
   ```

   このモデルでは、リクエストに E メールアドレスを含める必要があります。

1. **[保存]** を選択します。

このステップでは、WebSocket API のルートを作成します。

**ルートを作成するには**

1. メインナビゲーションペインで、**[ルート]** を選択します。

1. [**ルートの作成**] を選択します。

1. [**Route key**] (ルートキー) に「**sendMessage**」と入力します。

1. 統合タイプを選択し、統合エンドポイントを指定します。詳細については、「[API Gateway での WebSocket API の統合](apigateway-websocket-api-integrations.md)」を参照してください。

1. [**ルートの作成**] を選択します。

このステップでは、`sendMessage` ルートに対するリクエストの検証を設定します。

**リクエストの検証を設定するには**

1. **[ルートリクエスト]** タブの **[ルートリクエスト設定]** で、**[編集]** を選択します。

1. **[モデル選択式]** に、「**\$1\$1request.body.messageType\$1**」と入力します。

   API Gateway は、`messageType` プロパティを使用して受信リクエストを検証します。

1. **[リクエストモデルを追加]** を選択します。

1. **[モデルキー]** に、「**email**」と入力します。

1. **[モデル]**] で、**[emailModel]** を選択します。

   API Gateway は、`messageType` プロパティが `email` に設定されている受信メッセージを、このモデルと照合して検証します。
**注記**  
API Gateway は、モデル選択式とモデルキーを一致させることができない場合、`$default` モデルを選択します。`$default` モデルが存在しない場合、検証は失敗します。本番稼働 API の場合は、`$default` モデルを作成することをお勧めします。

1. **[Save changes]** (変更の保存) をクリックします。

このステップでは、API をデプロイしてテストします。

**API をデプロイしてテストするには**

1. [**API のデプロイ**] を選択します。

1. ドロップダウンリストから目的のステージを選択するか、新しいステージの名前を入力します。

1. **[デプロイ]** をクリックします。

1. メインナビゲーションペインで、**[ステージ]** を選択します。

1. API の WebSocket URL をコピーします。URL は `wss://abcdef123.execute-api.us-east-2.amazonaws.com/production` のようになります。

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

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

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

1. 次のコマンドを使用して API をテストします。

   ```
   {"action": "sendMessage", "messageType": "email"}
   ```

   ```
   {"message": "Invalid request body", "connectionId":"ABCD1=234", "requestId":"EFGH="}
   ```

   API Gateway はリクエストを失敗させます。

   次のコマンドを使用して API に有効なリクエストを送信します。

   ```
   {"action": "sendMessage", "messageType": "email", "address": "mary_major@example.com"}
   ```

# API Gateway での WebSocket API のデータ変換
<a name="websocket-api-data-transformations"></a>

API Gateway では、API のメソッドリクエストは、バックエンドで必要となる、該当する統合リクエストペイロードとは異なる形式のペイロードを受け取ることができます。同様に、バックエンドは、フロントエンドで予期されるメソッドレスポンスペイロードとは異なる統合レスポンスペイロードを返す場合があります。

API Gateway では、マッピングテンプレート変換を使用して、ペイロードをメソッドリクエストから該当する統合リクエストにマッピングしたり、統合レスポンスから該当するメソッドレスポンスにマッピングしたりできます。マッピングテンプレートを作成し、テンプレート選択式を指定して、必要なデータ変換の実行に使用するテンプレートを決定します。

データマッピングを使用して、[ルートリクエスト](api-gateway-basic-concept.md#apigateway-definition-route-request)からバックエンド統合にデータをマッピングできます。詳細については、「[API Gateway で WebSocket API のデータマッピングを設定する](websocket-api-data-mapping.md)」を参照してください。

## テンプレートとモデルのマッピング
<a name="apigateway-websocket-api-mapping-templats-and-models"></a>

 *マッピングテンプレート*は、[Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) で表現されるスクリプトであり、[JSONPath 式](https://goessner.net/articles/JsonPath/)を使用してペイロードに適用されます。API Gateway マッピングテンプレートの詳細については、「[API Gateway での REST API のテンプレート変換のマッピング](models-mappings.md)」を参照してください。

ペイロードでは、[JSON スキーマのドラフト 4](https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04) に基づく*データモデル*を使用できます。マッピングテンプレートを作成するためにモデルを定義する必要はありません。ただし、API Gateway では指定されたモデルに基づいてテンプレート設計図が生成されるため、モデルはテンプレートの作成に役立ちます。API Gateway モデルの詳細については、「[REST API のデータモデル](models-mappings-models.md)」を参照してください。

## テンプレート選択式
<a name="apigateway-websocket-api-template-selection-expressions"></a>

マッピングテンプレートを使用してペイロードを変換するには、[統合リクエスト](apigateway-websocket-api-integration-requests.md)または[統合レスポンス](apigateway-websocket-api-integration-responses.md)で WebSocket API テンプレート選択式を指定します。この式の評価により、(入力テンプレートを介して) リクエストボディを統合リクエストボディに変換するか、(出力テンプレートを介して) 統合レスポンスボディをルートレスポンスボディに変換するために使用される入力または出力テンプレート (存在する場合) が決定されます。

`Integration.TemplateSelectionExpression` は、`${request.body.jsonPath}` および静的な値をサポートします。

`IntegrationResponse.TemplateSelectionExpression` は、`${request.body.jsonPath}`、`${integration.response.statuscode}`、`${integration.response.header.headerName}`、`${integration.response.multivalueheader.headerName}` および静的な値をサポートします。

## 統合レスポンスの選択式
<a name="apigateway-websocket-api-integration-response-selection-expressions"></a>

WebSocket API に対して[統合レスポンス](apigateway-websocket-api-integration-responses.md)を設定するときは、オプションで統合レスポンスの選択式を指定できます。この式により、統合が返されるときに選択する `[https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid-integrationresponses-integrationresponseid.html](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid-integrationresponses-integrationresponseid.html)` が決定されます。現在、この式の値は以下に定義するように、API Gateway によって制限されています。この式は*非プロキシ統合*に対してのみ適用されることに注意してください。プロキシ統合は、モデル化または変更なしに、単純にレスポンスペイロードを呼び出し元に渡すだけです。

上記に示した他の選択式とは異なり、この式は*パターンマッチング*形式を現在サポートしています。式はスラッシュで囲む必要があります。

現在、値は `[https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid.html#apis-apiid-integrations-integrationid-prop-integration-integrationtype](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid.html#apis-apiid-integrations-integrationid-prop-integration-integrationtype)` に応じて固定されています。
+ Lambda ベースの統合の場合は、`$integration.response.body.errorMessage` です。
+ `HTTP` および `MOCK` 統合の場合、その値は `$integration.response.statuscode` です。
+ `HTTP_PROXY` と `AWS_PROXY` の場合、式は利用されません。これは、呼び出し元へのペイロードのパススルーをリクエストしているためです。

# API Gateway で WebSocket API のデータマッピングを設定する
<a name="websocket-api-data-mapping"></a>

*データマッピング*を使用すると、[ルートリクエスト](api-gateway-basic-concept.md#apigateway-definition-route-request)からバックエンド統合にデータをマッピングできます。

**注記**  
WebSocket API のデータマッピングは、 ではサポートされていませんAWS マネジメントコンソール データマッピングを設定するには、AWS CLI、AWS CloudFormation、または SDK を使用する必要があります。

**Topics**
+ [ルートリクエストデータを統合リクエストパラメータにマッピングする](#websocket-mapping-request-parameters)
+ [例](#websocket-data-mapping-examples)

## ルートリクエストデータを統合リクエストパラメータにマッピングする
<a name="websocket-mapping-request-parameters"></a>

統合リクエストパラメータは、定義されたルートリクエストパラメータ、リクエストボディ、[`context`](api-gateway-mapping-template-reference.md#context-variable-reference) または [`stage`](api-gateway-mapping-template-reference.md#stagevariables-template-reference) 変数、静的値からマッピングできます。

次の表は、統合リクエストのデータマッピング式を示しています。表で、*`PARAM_NAME`* は、特定のパラメータ型のルートリクエストパラメータの名前です。正規表現パターン `'^[a-zA-Z0-9._$-]+$]'` に一致する必要があります。*JSONPath\$1EXPRESSION* はリクエストボディの JSON フィールドの JSONPath 式です。


| マッピングされたデータソース | マッピング式 | 
| --- | --- | 
| リクエストクエリ文字列 (\$1connect ルートでのみサポート) | route.request.querystring.PARAM\$1NAME | 
| リクエストヘッダー (\$1connect ルートでのみサポート) | route.request.header.PARAM\$1NAME | 
| 複数値のリクエストクエリ文字列 (\$1connect ルートでのみサポート) | route.request.multivaluequerystring.PARAM\$1NAME | 
| 複数値のリクエストヘッダー (\$1connect ルートでのみサポート) | route.request.multivalueheader.PARAM\$1NAME | 
| リクエストボディ | route.request.body.JSONPath\$1EXPRESSION | 
| ステージ変数 | stageVariables.VARIABLE\$1NAME | 
| コンテキスト変数 | [サポートされるコンテキスト変数](api-gateway-mapping-template-reference.md#context-variable-reference)の 1 つである必要がある context.VARIABLE\$1NAME。 | 
| 静的な値 | 'STATIC\$1VALUE'。STATIC\$1VALUE はリテラル文字列であり、単一引用符で囲む必要があります。 | 

データマッピングを作成するときは、AWS CLI を使用して、AWS CLI の文字列でリテラルを使用するための正しい形式に従ってください。詳細については、「*AWS Command Line Interface ユーザーガイド*」の「[AWS CLI で文字列に引用符とリテラルを使用する](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-quoting-strings.html)」を参照してください。

## 例
<a name="websocket-data-mapping-examples"></a>

以下の AWS CLI の例では、データマッピングを設定しています。CloudFormation テンプレートの例については、「[samples/websocket-data-mapping.zip](samples/websocket-data-mapping.zip)」を参照してください。

### クライアントの connectionId を統合リクエストのヘッダーにマッピングする
<a name="websocket-data-mapping-examples.connectionId"></a>

次の [update-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-integration.html) コマンドは、クライアントの `connectionId` をバックエンド統合へのリクエストの `connectionId` ヘッダーにマッピングします。

```
aws apigatewayv2 update-integration \
    --integration-id abc123 \
    --api-id a1b2c3d4 \ 
    --request-parameters 'integration.request.header.connectionId'='context.connectionId'
```

### クエリ文字列パラメータを統合リクエストのヘッダーにマッピングする
<a name="websocket-data-mapping-examples.querystring"></a>

次の例では、`authToken` クエリ文字列パラメータを統合リクエストの `authToken` ヘッダーにマッピングします。

1. 次の [update-route](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-route.html) コマンドを使用して、`authToken` クエリ文字列パラメータをルートのリクエストパラメータに追加します。

   ```
   aws apigatewayv2 update-route --route-id 0abcdef \
       --api-id a1b2c3d4 \
       --request-parameters '{"route.request.querystring.authToken": {"Required": false}}'
   ```

1.  次の [update-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-integration.html) コマンドを使用して、クエリ文字列パラメータをバックエンド統合へのリクエストの `authToken` ヘッダーにマッピングします。

   ```
   aws apigatewayv2 update-integration \
       --integration-id abc123 \
       --api-id a1b2c3d4 \
       --request-parameters 'integration.request.header.authToken'='route.request.querystring.authToken'
   ```

1. (オプション) 必要に応じて、次の [delete-route-request-parameter](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/delete-route-request-parameter.html) を使用して、ルートのリクエストパラメータから `authToken` クエリ文字列パラメータを削除します。

   ```
   aws apigatewayv2 delete-route-request-parameter \
       --route-id 0abcdef \
       --api-id a1b2c3d4 \
       --request-parameter-key 'route.request.querystring.authToken'
   ```

# API Gateway の WebSocket API マッピングテンプレートのリファレンス
<a name="apigateway-websocket-api-mapping-template-reference"></a>

このセクションでは、API Gateway の WebSocket API で現在サポートされている一連の変数の概要を示します。


| パラメータ | 説明 | 
| --- | --- | 
| \$1context.connectionId |  クライアントへのコールバックを行うために使用できる接続の一意の ID。  | 
| \$1context.connectedAt |  [エポック](https://en.wikipedia.org/wiki/Unix_time)形式の接続時間。  | 
| \$1context.domainName |  WebSocket API のドメイン名。これは、(ハードコーディングされた値の代わりに) クライアントへのコールバックを行うために使用できます。  | 
| \$1context.eventType |  イベントタイプ: (`CONNECT`、`MESSAGE`、または `DISCONNECT`)。  | 
| \$1context.messageId |  メッセージの一意のサーバー側 ID。`$context.eventType` が `MESSAGE` である場合のみ利用できます。  | 
| \$1context.routeKey |  選択されたルートキー。  | 
| \$1context.requestId |  `$context.extendedRequestId` と同じ  | 
| \$1context.extendedRequestId | 自動生成された API コールの ID。デバッグとトラブルシューティングにさらに役立つ情報が含まれています。 | 
| \$1context.apiId |  API Gateway が API に割り当てる識別子。  | 
| \$1context.authorizer.principalId |  クライアントにより送信され、API Gateway Lambda オーソライザー (以前のカスタムオーソライザー) の Lambda 関数から返されたトークンと関連付けられたプリンシパルユーザー ID。  | 
| \$1context.authorizer.property |  API Gateway Lambda オーソライザーの関数から返された `context` マップの指定されたキー/値ペアの文字列化された値。たとえば、オーソライザーが次の `context` マップを返すとします。 <pre>"context" : {<br />  "key": "value",<br />  "numKey": 1,<br />  "boolKey": true<br />}</pre> `$context.authorizer.key` の呼び出しでは `"value"` 文字列が返され、`$context.authorizer.numKey` の呼び出しでは `"1"` 文字列が返され、`$context.authorizer.boolKey` の呼び出しでは `"true"` 文字列が返されます。  | 
| \$1context.error.messageString | \$1context.error.message を引用符で囲んだ値、つまり "\$1context.error.message"。 | 
| \$1context.error.validationErrorString |  詳細な検証エラーメッセージを含む文字列。  | 
| \$1context.identity.accountId |  リクエストに関連付けられた AWS アカウント ID です。  | 
| \$1context.identity.apiKey |  キー対応 API リクエストに関連付けられた API 所有者キー。  | 
| \$1context.identity.apiKeyId | キー対応 API リクエストに関連付けられた API キー ID。 | 
| \$1context.identity.caller |  リクエストを実行している発信者のプリンシパル ID です。  | 
| \$1context.identity.cognitoAuthenticationProvider |  リクエスト元の発信者が使用するすべての Amazon Cognito 認証プロバイダーのカンマ区切りのリスト。リクエストが Amazon Cognito 認証情報で署名されている場合にのみ使用できます。 たとえば、Amazon Cognito ユーザープールのアイデンティティの場合、`cognito-idp. region.amazonaws.com/user_pool_id,cognito-idp.region.amazonaws.com/user_pool_id:CognitoSignIn:token subject claim` 利用可能な Amazon Cognito 認証プロバイダーについては、「Amazon Cognito 開発者ガイド」の「[フェデレーティッド ID の使用](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html)」を参照してください。** | 
| \$1context.identity.cognitoAuthenticationType |  リクエストを行う発信者の Amazon Cognito 認証タイプ。リクエストが Amazon Cognito 認証情報で署名されている場合にのみ使用できます。有効な値は、認証されたアイデンティティ`authenticated`および認証されていないアイデンティティ`unauthenticated`です。 | 
| \$1context.identity.cognitoIdentityId |  リクエストを行う発信者の Amazon Cognito ID。リクエストが Amazon Cognito 認証情報で署名されている場合にのみ使用できます。  | 
| \$1context.identity.cognitoIdentityPoolId |  リクエストを行う発信者の Amazon Cognito ID プール ID。リクエストが Amazon Cognito 認証情報で署名されている場合にのみ使用できます。  | 
| \$1context.identity.sourceIp |  API Gateway エンドポイントへのリクエストを実行する即時 TCP 接続のソース IP アドレス。  | 
| \$1context.identity.user |  リクエストを実行しているユーザーのプリンシパル ID です。  | 
| \$1context.identity.userAgent |  API 発信者のユーザーエージェントです。  | 
| \$1context.identity.userArn |  認証後に識別された有効ユーザーの Amazon リソースネーム (ARN) です。  | 
| \$1context.requestTime | [CLF](https://httpd.apache.org/docs/current/logs.html#common) 形式の要求時間 (dd/MMM/yyyy:HH:mm:ss \$1-hhmm)。 | 
| \$1context.requestTimeEpoch | [エポック](https://en.wikipedia.org/wiki/Unix_time)形式のリクエスト時間 (ミリ秒単位)。 | 
| \$1context.stage |  API コールの開発ステージ (Beta、Prod など)。  | 
| \$1context.status |  レスポンスステータス。  | 
| \$1input.body | 文字列として raw ペイロードを返します。 | 
| \$1input.json(x) | この関数は、JSONPath の式を評価し、結果を JSON 文字列で返します。 たとえば `$input.json('$.pets')` は、ペットの構造を表す JSON 文字列を返します。 JSONPath の詳細については、[JSONPath](https://goessner.net/articles/JsonPath/) または [JSONPath for Java](https://github.com/json-path/JsonPath) を参照してください。 | 
| \$1input.path(x) | JSONPath 式文字列 (`x`) を受け取り、結果の JSON オブジェクト表現を返します。これにより、[Apache Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) でペイロード要素にネイティブにアクセスして操作できます。 たとえば、式 `$input.path('$.pets')` が次のようにオブジェクトを返すとします。 <pre>[<br />  { <br />    "id": 1, <br />    "type": "dog", <br />    "price": 249.99 <br />  }, <br />  { <br />    "id": 2, <br />    "type": "cat", <br />    "price": 124.99 <br />  }, <br />  { <br />    "id": 3, <br />    "type": "fish", <br />    "price": 0.99 <br />  } <br />]</pre> `$input.path('$.pets').count()` は `"3"` を返します。 JSONPath の詳細については、[JSONPath](http://goessner.net/articles/JsonPath/) または [JSONPath for Java](https://github.com/jayway/JsonPath) を参照してください。 | 
| \$1stageVariables.<variable\$1name> |  *<variable\$1name>* はステージ変数名を表します。  | 
| \$1stageVariables['<variable\$1name>'] |  *<variable\$1name>* は任意のステージ変数名を表します。  | 
| \$1\$1stageVariables['<variable\$1name>']\$1 |  *<variable\$1name>* は任意のステージ変数名を表します。  | 
| \$1util.escapeJavaScript() |  JavaScript 文字列ルールを使用して文字列内の文字をエスケープします。  この関数は、通常の一重引用符 (`'`) をエスケープした一重引用符 (`\'`) に変換します。ただし、エスケープした一重引用符は JSON で有効ではありません。したがって、この関数からの出力を JSON のプロパティで使用する場合、エスケープした一重引用符 (`\'`) を通常の一重引用符 (`'`) に戻す必要があります。これを次の例で示します:  <pre> $util.escapeJavaScript(data).replaceAll("\\'","'")</pre>   | 
| \$1util.parseJson() |   "stringified" JSON を受け取り、結果のオブジェクト表現を返します。この関数の結果を使用して、Apache Velocity Template Language (VTL) でペイロード要素にネイティブにアクセスしてこれらの要素を操作できるようになります。たとえば、次のペイロードがあるとします。 <pre>{"errorMessage":"{\"key1\":\"var1\",\"key2\":{\"arr\":[1,2,3]}}"}</pre>  さらに、次のマッピングテンプレートを使用するとします。 <pre>#set ($errorMessageObj = $util.parseJson($input.path('$.errorMessage')))<br />{<br />   "errorMessageObjKey2ArrVal" : $errorMessageObj.key2.arr[0]<br />}<br /></pre> この場合、次の出力が返されます。 <pre>{<br />   "errorMessageObjKey2ArrVal" : 1<br />}<br /></pre>  | 
| \$1util.urlEncode() | 文字列を「application/x-www-form-urlencoded」形式に変換します。 | 
| \$1util.urlDecode() | 「application/x-www-form-urlencoded」文字列をデコードします。 | 
| \$1util.base64Encode() | データを base64 エンコードされた文字列にエンコードします。 | 
| \$1util.base64Decode() | base64 エンコードされた文字列からデータをデコードします。 | 

# API Gateway での WebSocket API のバイナリメディアタイプ
<a name="websocket-api-develop-binary-media-types"></a>

現在、API Gateway WebSocket API は、受信メッセージのペイロードでバイナリフレームをサポートしていません。クライアントアプリがバイナリフレームを送信した場合、API Gateway はこれを拒否し、1003 コードでクライアントを切断します。

この動作には回避策があります。クライアントがテキストでエンコードされたバイナリデータ (Base64 など) をテキストフレームとして送信する場合、統合の `contentHandlingStrategy` プロパティを `CONVERT_TO_BINARY` に設定して、ペイロードを base64 エンコードの文字列からバイナリに変換できます。

プロキシ以外の統合でバイナリペイロードのルートレスポンスを返すには、統合レスポンスの `contentHandlingStrategy` プロパティを `CONVERT_TO_TEXT` に設定して、ペイロードをバイナリから base64 でエンコードされた文字列に変換できます。

# WebSocket API を呼び出す
<a name="apigateway-how-to-call-websocket-api"></a>

WebSocket API をデプロイすると、クライアントアプリケーションはそれに接続してメッセージを送信できます。また、バックエンドサービスは接続されたクライアントアプリケーションにメッセージを送信できます。
+ `wscat` を使用して WebSocket API に接続し、メッセージを送信してクライアントの動作をシミュレートできます。「[`wscat` を使用した WebSocket API への接続とメッセージの送信](apigateway-how-to-call-websocket-api-wscat.md)」を参照してください。
+ バックエンドサービスから @connections API を使用して、接続されたクライアントへのコールバックメッセージの送信、接続情報の取得、またはクライアントの切断を行うことができます。「[バックエンドサービスでの `@connections` コマンドの使用](apigateway-how-to-call-websocket-api-connections.md)」を参照してください。
+ クライアントアプリケーションは独自の WebSocket ライブラリを使用して、WebSocket API を呼び出すことができます。

# `wscat` を使用した WebSocket API への接続とメッセージの送信
<a name="apigateway-how-to-call-websocket-api-wscat"></a>

この `[wscat](https://www.npmjs.com/package/wscat)` ユーティリティは、API Gateway で作成してデプロイした WebSocket API をテストするための便利なツールです。`wscat` は以下のようにインストールして使用できます。

1. [https://www.npmjs.com/package/wscat](https://www.npmjs.com/package/wscat) から `wscat` をダウンロードします。

1. 次のコマンドを実行して `wscat` をインストールします。

   ```
   npm install -g wscat
   ```

1. API に接続するには、次の例のように `wscat` コマンドを実行します。この例では、`Authorization` 設定が `NONE` であることを前提としています。

   ```
   wscat -c wss://aabbccddee.execute-api.us-east-1.amazonaws.com/test/
   ```

   `aabbccddee` を実際の API ID に置き換える必要があります。これは API Gateway コンソールに表示されるか、AWS CLI [https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api.html](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api.html) コマンドによって返されます。

   さらに、API が `us-east-1` 以外のリージョンにある場合、正しいリージョンに置き換える必要があります。

1. API をテストするには、接続中に次のようなメッセージを入力します。

   ```
   {"{jsonpath-expression}":"{route-key}"}
   ```

   ここで、*\$1jsonpath-expression\$1* は JSONPath 式で、*\$1route-key\$1* は API のルートキーです。例:

   ```
   {"action":"action1"}
   {"message":"test response body"}
   ```

   JSONPath の詳細については、[JSONPath](https://goessner.net/articles/JsonPath/) または [JSONPath for Java](https://github.com/json-path/JsonPath) を参照してください。

1. API から切断するには、「`ctrl-C`」と入力します。

# バックエンドサービスでの `@connections` コマンドの使用
<a name="apigateway-how-to-call-websocket-api-connections"></a>

バックエンドサービスは次の WebSocket 接続 HTTP リクエストを使用して、接続されたクライアントへのコールバックメッセージの送信、接続情報の取得、またはクライアントの切断を行うことができます。

**重要**  
これらのリクエストは [IAM 認可](apigateway-websocket-control-access-iam.md)を使用するため、[署名バージョン 4 (SigV4)](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html) を使用して署名する必要があります。これを行うには、API Gateway 管理 API を使用します。詳細については、「[ApiGatewayManagementApi](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/apigatewaymanagementapi.html)」を参照してください。

次のコマンドでは、`{api-id}` を実際の API ID に置き換える必要があります。この ID は API Gateway コンソールに表示されるか、AWS CLI [create-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api.html) コマンドから返されます。このコマンドを使用する前に接続を確立する必要があります。

コールバックメッセージをクライアントに送信するには、以下を使用します。

```
POST https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}/@connections/{connection_id}
```

以下の例のように、`[Postman](https://www.postman.com/)` を使用するか、`[awscurl](https://github.com/okigan/awscurl)` を呼び出すことで、このリクエストをテストできます。

```
awscurl --service execute-api -X POST -d "hello world" https://{prefix}.execute-api.us-east-1.amazonaws.com/{stage}/@connections/{connection_id}
```

次の例のようにコマンドを URL でエンコードする必要があります。

```
awscurl --service execute-api -X POST -d "hello world" https://aabbccddee.execute-api.us-east-1.amazonaws.com/prod/%40connections/R0oXAdfD0kwCH6w%3D
```

クライアントの最新の接続ステータスを取得するには、以下を使用します。

```
GET https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}/@connections/{connection_id}
```

クライアントを切断するには、以下を使用します。

```
DELETE https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}/@connections/{connection_id}
```

統合で `$context` 変数を使用して、コールバック URL を動的に構築できます。例えば、`Node.js` Lambda 関数で Lambda プロキシの統合を使用する場合は、次のように URL を構築し、接続されたクライアントにメッセージを送信できます。

```
import {
  ApiGatewayManagementApiClient,
  PostToConnectionCommand,
} from "@aws-sdk/client-apigatewaymanagementapi";

export const handler = async (event) => {
  const domain = event.requestContext.domainName;
  const stage = event.requestContext.stage;
  const connectionId = event.requestContext.connectionId;
  const callbackUrl = `https://${domain}/${stage}`;
  const client = new ApiGatewayManagementApiClient({ endpoint: callbackUrl });

  const requestParams = {
    ConnectionId: connectionId,
    Data: "Hello!",
  };

  const command = new PostToConnectionCommand(requestParams);

  try {
    await client.send(command);
  } catch (error) {
    console.log(error);
  }

  return {
    statusCode: 200,
  };
};
```

WebSocket API にカスタムドメイン名を使用する場合は、関数コードから `stage` 変数を削除します。

コールバックメッセージを送信する場合、Lambda 関数には API ゲートウェイ管理 API を呼び出すアクセス許可が必要です。接続が確立される前、またはクライアントの接続が切断された後にメッセージを投稿すると、`GoneException` を含むエラーが表示される場合があります。

# WebSocket API を公開してユーザーが呼び出せるようにする
<a name="websocket-api-publish"></a>

API Gateway API を作成して開発するだけでは、ユーザーが自動的に呼び出せるようにはなりません。呼び出し可能にするには、API をステージにデプロイする必要があります。さらに、ユーザーが API にアクセスするために使用する URL をカスタマイズすることもできます。ブランドと一致するドメインや、API のデフォルト URL よりも記憶に残るドメインを指定できます。

このセクションでは、API をデプロイし、アクセスするためにユーザーに提供する URL をカスタマイズする方法を説明しています。

**注記**  
API Gateway API のセキュリティを強化するため、`execute-api.{region}.amazonaws.com` ドメインは[パブリックサフィックスリスト (PSL)](https://publicsuffix.org/) に登録されます。セキュリティ強化のため、API Gateway API のデフォルトドメイン名に機密な Cookie を設定する必要が生じた場合は、`__Host-` プレフィックスの付いた Cookie の使用をお勧めします。このプラクティスは、クロスサイトリクエストフォージェリ (CSRF) 攻撃からドメインを防ぐ際に役立ちます。詳細については、Mozilla 開発者ネットワークの「[Set-Cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#cookie_prefixes)」ページを参照してください。

**Topics**
+ [API Gateway で WebSocket API のステージを作成する](websocket-api-stages.md)
+ [API Gateway で WebSocket API をデプロイする](apigateway-set-up-websocket-deployment.md)
+ [API Gateway での WebSocket API のセキュリティポリシー](websocket-api-ciphers.md)
+ [API Gateway での WebSocket API のカスタムドメイン名](websocket-api-custom-domain-names.md)

# API Gateway で WebSocket API のステージを作成する
<a name="websocket-api-stages"></a>

API ステージは、API のライフサイクル状態への論理的なリファレンスです (例: `dev`、`prod`、`beta`、`v2` など)。API ステージは API ID とステージ名で識別され、API の呼び出しに使用する URL に含まれます。各ステージは、API のデプロイの名前付きリファレンスで、クライアントアプリケーションから呼び出すことができます。

デプロイは、API 設定のスナップショットです。ステージに API をデプロイすると、クライアントがその API を呼び出すことができます。変更を有効にするには、API をデプロイする必要があります。

## ステージ変数
<a name="websocket-api-stages.stage-variables"></a>

ステージ変数は、WebSocket API のステージに対して定義できるキーと値のペアです。環境変数と同様に機能し、API のセットアップで使用できます。

たとえば、ステージ変数を定義し、その値を HTTP プロキシ統合の HTTP エンドポイントとして設定することができます。後で、関連付けられたステージ変数名を使用してエンドポイントを参照できます。これにより、各ステージで異なるエンドポイントで同じ API セットアップを使用できます。同様に、ステージ変数を使用して、API の各ステージに異なる AWS Lambda 関数の統合を指定できます。

**注記**  
ステージ変数は、認証情報などの機密データに使用されることを意図していません。機密データを統合に渡すには、AWS Lambda オーソライザーを使用します。Lambda オーソライザーの出力では、機密データを統合に渡すことができます。詳細については、「[Lambda オーソライザーのレスポンス形式](http-api-lambda-authorizer.md#http-api-lambda-authorizer.payload-format-response)」を参照してください。

### 例
<a name="websocket-api-stages.stage-variables-examples"></a>

ステージ変数を使用して HTTP 統合エンドポイントをカスタマイズするには、まずステージ変数の名前と値 (`url` など) を `example.com` の値で設定する必要があります。次に、HTTP プロキシ統合を設定します。エンドポイントの URL を入力する代わりに、ステージ変数の値、**http://\$1\$1stageVariables.url\$1** を使用するように API Gateway に指示できます 。この値を指定すると、API Gateway は、ランタイムに API のステージに応じてステージ変数の `${}` を置き換えます。

同様に、ステージ変数を参照して Lambda 関数名や AWS のロールの ARN を指定することができます。

ステージ変数値として Lambda 関数名を指定する場合は、その Lambda 関数に対するアクセス許可を手動で設定する必要があります。次の [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) コマンドは、必要なアクセス許可を追加します。

```
aws lambda add-permission --function-name arn:aws:lambda:XXXXXX:your-lambda-function-name --source-arn arn:aws:execute-api:us-east-1:YOUR_ACCOUNT_ID:api_id/*/HTTP_METHOD/resource --principal apigateway.amazonaws.com --statement-id apigateway-access --action lambda:InvokeFunction
```

## API Gateway のステージ変数のリファレンス
<a name="websocket-api-stages.stage-variables-reference"></a>

### HTTP 統合 URI
<a name="websocket-api-stages.stage-variables-in-integration-HTTP-uris"></a>

ステージ変数は、次の例に示すように、HTTP 統合 URI の一部として使用できます。
+ プロトコルのない完全な URI – `http://${stageVariables.<variable_name>}`
+ 完全なドメイン – `http://${stageVariables.<variable_name>}/resource/operation`
+ サブドメイン – `http://${stageVariables.<variable_name>}.example.com/resource/operation`
+ パス – `http://example.com/${stageVariables.<variable_name>}/bar`
+ クエリ文字列 – `http://example.com/foo?q=${stageVariables.<variable_name>}` 

### Lambda 関数
<a name="websocket-api-stages.stage-variables-in-integration-lambda-functions"></a>

 ステージ変数は、次の例に示すように、Lambda 関数名やエイリアスの代わりに使用できます。
+ `arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<region>:<account_id>:function:${stageVariables.<function_variable_name>}/invocations`
+ `arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<region>:<account_id>:function:<function_name>:${stageVariables.<version_variable_name>}/invocations`

**注記**  
Lambda 関数にステージ変数を使用するには、関数が API と同じアカウントにある必要があります。ステージ変数は、クロスアカウント Lambda 関数をサポートしていません。

### AWS 統合認証情報
<a name="websocket-api-stages.stage-variables-in-integration-aws-credentials"></a>

 次の例に示すように、ステージ変数を AWS ユーザーまたはロールの認証情報 ARN の一部として使用できます。
+  `arn:aws:iam::<account_id>:${stageVariables.<variable_name>}` 

# API Gateway で WebSocket API をデプロイする
<a name="apigateway-set-up-websocket-deployment"></a>

 WebSocket API を作成したら、この API をデプロイしてユーザーが呼び出せるようにする必要があります。

API をデプロイするには、[API デプロイ](api-gateway-basic-concept.md#apigateway-definition-api-deployment)を作成し、それを [ステージ](api-gateway-basic-concept.md#apigateway-definition-api-stage)に関連付けます。各ステージは、API のスナップショットであり、クライアントアプリが呼び出し可能になります。

**重要**  
API を更新するたびに、API を再デプロイする必要があります。ステージ設定以外の変更には、以下のリソースへの変更も含めて、再デプロイが必要です。  
ルート
統合
オーソライザー
API ごとのステージ数は、デフォルトで 10 個に制限されています。デプロイでステージを再利用することをお勧めします。

デプロイされた WebSocket API を呼び出すため、クライアントはメッセージを API の URL に送信します。URL は、API のホスト名とステージ名によって決定されます。

**注記**  
API Gateway は最大 128 KB までのペイロードをサポートし、最大フレームサイズは 32 KB です。メッセージが 32 KB を超えた場合は、それぞれを 32 KB 以下の複数のフレームに分割する必要があります。

API のデフォルトドメイン名を使用すると、特定のステージ (`{stageName}`) の WebSocket API の URL は、たとえば次の形式になります。

```
wss://{api-id}.execute-api.{region}.amazonaws.com/{stageName}
```

WebSocket API のデフォルトのベース URL をよりユーザーフレンドリなものにするには、カスタムドメイン名 (例: `api.example.com`) を作成し、API のデフォルトのホスト名と置き換えることができます。設定プロセスは、REST API と同じです。詳細については、「[API Gateway でのパブリック REST API のカスタムドメイン名](how-to-custom-domains.md)」を参照してください。

ステージを使用すると、API の堅牢なバージョン管理が可能になります。たとえば、API を `test` ステージと、`prod` ステージにデプロイし、`test` ステージをテストビルドとして使用し、`prod` ステージを安定したビルドとして使用できます。更新がテストに合格したら、`test` ステージを `prod` ステージに昇格させることができます。昇格は、`prod` ステージに API を再デプロイすることで実行できます。ステージの詳細については、「[API Gateway で REST API のステージをセットアップする](set-up-stages.md)」を参照してください。

**Topics**
+ [AWS CLI を使用して WebSocket API デプロイを作成する](#apigateway-create-websocket-deployment-using-awscli)
+ [API Gateway コンソールを使用して WebSocket API デプロイを作成する](#apigateway-create-websocket-deployment-using-console)

## AWS CLI を使用して WebSocket API デプロイを作成する
<a name="apigateway-create-websocket-deployment-using-awscli"></a>

次の [create-deployment](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-deployment.html) コマンドでは、デプロイを作成します。

```
aws apigatewayv2 --region us-east-1 create-deployment --api-id aabbccddee
```

出力は次のようになります。

```
{
    "DeploymentId": "fedcba",
    "DeploymentStatus": "DEPLOYED",
    "CreatedDate": "2018-11-15T06:49:09Z"
}
```

このデプロイをステージに関連付けるまで、デプロイされた API は呼び出し可能ではありません。新しいステージを作成するか、以前に作成したステージを再利用できます。

次の [create-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-stage.html) コマンドは、新しいステージを作成し、それをデプロイに関連付けます。

```
aws apigatewayv2 --region us-east-1 create-stage --api-id aabbccddee --deployment-id fedcba --stage-name test
```

出力は次のようになります。

```
{
    "StageName": "test",
    "CreatedDate": "2018-11-15T06:50:28Z",
    "DeploymentId": "fedcba",
    "DefaultRouteSettings": {
        "MetricsEnabled": false,
        "ThrottlingBurstLimit": 5000,
        "DataTraceEnabled": false,
        "ThrottlingRateLimit": 10000.0
    },
    "LastUpdatedDate": "2018-11-15T06:50:28Z",
    "StageVariables": {},
    "RouteSettings": {}
}
```

また、ステージの `deploymentId` プロパティを新しく作成されたデプロイ ID (*deployment-id*) で更新することにより、既存のステージを再利用することもできます。次の [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-stage.html) コマンドは、ステージのデプロイ ID を更新します。

```
aws apigatewayv2 update-stage --region region \
    --api-id api-id \ 
    --stage-name stage-name \ 
    --deployment-id deployment-id
```

## API Gateway コンソールを使用して WebSocket API デプロイを作成する
<a name="apigateway-create-websocket-deployment-using-console"></a>

API Gateway コンソールを使用して WebSocket API のデプロイを作成するには、次の作業を行います。

1. API Gateway コンソールにサインインし、API を選択します。

1. [**API のデプロイ**] を選択します。

1. ドロップダウンリストから目的のステージを選択するか、新しいステージの名前を入力します。

# API Gateway での WebSocket API のセキュリティポリシー
<a name="websocket-api-ciphers"></a>

API Gateway は、すべての WebSocket API エンドポイントに対して `TLS_1_2` のセキュリティポリシーを適用します。

*セキュリティポリシー*とは、Amazon API Gateway が提供する TLS の最小バージョンと暗号スイートの事前定義された組み合わせです。TLS プロトコルは、クライアントとサーバーの間の改ざんや傍受などのネットワークセキュリティの問題に対処します。クライアントがカスタムドメインを介して API に TLS ハンドシェイクを確立すると、セキュリティポリシーにより、TLS バージョンと暗号スイートのオプションが適用されます。ここで使用するオプションは、クライアントが選択できます。このセキュリティポリシーは、TLS 1.2 および TLS 1.3 トラフィックを受け入れ、TLS 1.0 トラフィックを拒否します。

## WebSocket API でサポートされている TLS プロトコルと暗号
<a name="websocket-api-custom-domain-ciphers-list"></a>

次の表では、WebSocket API でサポートされている TLS プロトコルについて説明します。


| **TLS プロトコル** | **TLS\$11\$12 セキュリティポリシー** | 
| --- | --- | 
| TLSv1.3 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| TLSv1.2 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 

次の表は、WebSocket API の TLS 1\$12 セキュリティポリシーで使用できる TLS 暗号について説明しています。


| **TLS 暗号** | **TLS\$11\$12 セキュリティポリシー** | 
| --- | --- | 
| TLS\$1AES\$1128\$1GCM\$1SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| TLS\$1AES\$1256\$1GCM\$1SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| TLS\$1CHACHA20\$1POLY1305\$1SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| ECDHE-ECDSA-AES128-GCM-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| ECDHE-RSA-AES128-GCM-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| ECDHE-ECDSA-AES128-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| ECDHE-RSA-AES128-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| ECDHE-ECDSA-AES256-GCM-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| ECDHE-RSA-AES256-GCM-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| ECDHE-ECDSA-AES256-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| ECDHE-RSA-AES256-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| AES128-GCM-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| AES128-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| AES256-GCM-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 
| AES256-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/success_icon.svg) はい | 

## OpenSSL および RFC の暗号名
<a name="apigateway-secure-connections-openssl-rfc-cipher-names-websocket"></a>

OpenSSL と IETF RFC 5246 では、同じ暗号に異なる名前を使用します。暗号名のリストについては、「[OpenSSL および RFC の暗号名](apigateway-security-policies-list.md#apigateway-secure-connections-openssl-rfc-cipher-names)」を参照してください。

## REST API と HTTP API に関する情報
<a name="apigateway-websocket-additional-apis"></a>

REST API と HTTP API の詳細については、「[API Gateway でカスタムドメインのセキュリティポリシーを選択する](apigateway-custom-domain-tls-version.md)」と「[API Gateway での HTTP API のセキュリティポリシー](http-api-ciphers.md)」を参照してください。

# API Gateway での WebSocket API のカスタムドメイン名
<a name="websocket-api-custom-domain-names"></a>

*カスタムドメイン名*は、API ユーザーに提供できる、よりシンプルで直感的な URL です。

API のデプロイ後、お客様 (およびその顧客) は、以下の形式のデフォルトのベース URL を使用して API を呼び出すことができます。

```
https://api-id.execute-api.region.amazonaws.com/stage
```

*api-id* は API Gateway が生成します。*region* は AWS リージョンであり、*stage* は API のデプロイ時にユーザーが指定します。

URL のホスト名の部分 (`api-id.execute-api.region.amazonaws.com`) は、API エンドポイントを参照します。デフォルトの API エンドポイント名は、ランダムに生成され、再呼び出しが難しく、ユーザーフレンドリではありません。

カスタムドメイン名を使用すると、API のホスト名を設定し、代替パスを API にマッピングするための基本パス (`myservice` など) を選択できます。たとえば、API のよりわかりやすい ベース URL は以下のようになります。

```
https://api.example.com/myservice
```

## 考慮事項
<a name="websocket-api-custom-domain-names-considerations"></a>

以下の考慮事項は、カスタムドメイン名の使用に影響する可能性があります。
+ カスタムドメイン名を WebSocket API にマッピングする場合、REST API または HTTP API にマッピングすることはできません。
+ リージョン別カスタムドメイン名のみがサポートされます。
+ TLS の最小バージョンでは、TLS 1.2 のみがサポートされます。
+ API エンドポイントにマッピングするために DNS プロバイダーのリソースレコードを作成または更新する必要があります。このマッピングを行わないと、カスタムドメイン名宛ての API リクエストが API Gateway に届きません。
+ ワイルドカード証明書を使用すると、デフォルトのクォータを超えることなく、ほぼ無数のドメイン名をサポートできます。詳細については、「[ワイルドカードカスタムドメイン名](http-api-custom-domain-names.md#http-wildcard-custom-domain-names)」を参照してください。

## 前提条件
<a name="websocket-api-custom-domain-names-prerequisites"></a>

カスタムドメイン名の前提条件は、以下のとおりです。

### ドメイン名を登録する
<a name="websocket-api-custom-domain-names-register"></a>

API のカスタムドメイン名を設定するには、登録されたインターネットドメイン名が必要です。インターネットドメインを登録するには、[Amazon Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/) を使用するか、任意のサードパーティのドメインレジストラを使用できます。カスタムドメイン名は、登録したインターネットドメインのサブドメイン名またはルートドメイン名 ("Zone Apex" とも呼ばれます) にすることができます。

ドメイン名は [RFC 1035](https://tools.ietf.org/html/rfc1035#section-2.3.4) 仕様に準拠している必要があり、ラベルあたり最大 63オクテット、合計 255 オクテットを含めることができます。

### カスタムドメイン名の証明書
<a name="websocket-api-custom-domain-names-certificates"></a>

API のカスタムドメイン名を設定する前に、ACM で SSL/TLS 証明書を準備する必要があります。カスタムドメイン名を作成する AWS リージョンで ACM を使用できない場合は、そのリージョンの API Gateway に証明書をインポートする必要があります。

SSL/TLS 証明書をインポートするには、カスタムドメイン名の PEM 形式の SSL/TLS 認証本文、そのプライベートキー、およびカスタムドメイン名の証明書チェーンを提供する必要があります。

ACM に保存された各証明書は ARN によって識別されます。ACM 発行の証明書により、プライベートキーなど証明書の機密の詳細が漏れる心配はありません。AWS で管理された証明書をドメイン名で使用するには、その ARN を単に参照します。

アプリケーションで証明書ピンニング (SSL ピンニングとも呼ばれる) を使用して ACM 証明書を固定すると、AWS が証明書を更新した後にアプリケーションがドメインに接続できないことがあります。詳細については、「*AWS Certificate Manager ユーザーガイド*」の「[証明書のピンニングの問題](https://docs.aws.amazon.com/acm/latest/userguide/troubleshooting-pinning.html)」を参照してください。

## ワイルドカードカスタムドメイン名
<a name="websocket-api-wildcard-custom-domain-names"></a>

ワイルドカードカスタムドメイン名を使用すると、[デフォルトのクォータ](limits.md)を超えずにほぼ無数のドメイン名をサポートできます。たとえば、各お客様に個別のドメイン名を付けることができます `customername.api.example.com`。

ワイルドカードカスタムドメイン名を制作するためには、ルートドメインの可能なすべてのサブドメインを表すカスタムドメインの最初のサブドメインとして、ワイルドカード (`*`) を指定します。

たとえば、ワイルドカードカスタムドメイン名として `*.example.com` を使用すると、`a.example.com`、`b.example.com`、`c.example.com` などのサブドメインが生成され、これらはすべて同じドメインにルーティングされます。

ワイルドカードカスタムドメイン名は、API Gateway の標準のカスタムドメイン名とは異なる設定をサポートします。たとえば、1 つの AWS アカウントで、`*.example.com` と `a.example.com` を異なる動作に設定できます。

コンテキスト変数 `$context.domainName` と `$context.domainPrefix` コンテキスト変数を使用して、クライアントが API を呼び出すために使用したドメイン名を判断できます。コンテキスト変数の詳細については、「[API Gateway のデータ変換の変数](api-gateway-mapping-template-reference.md)」を参照してください。

ワイルドカードカスタムドメイン名を作成するには、DNS または E メール検証方法を使用して検証された証明書を ACM から発行してもらう必要があります。

**注記**  
別の AWS アカウントで作成済みのカスタムドメイン名と競合するようなワイルドカードカスタムドメイン名を作成することはできません。たとえば、アカウント A で `a.example.com` が作成済みである場合、アカウント B はワイルドカードカスタムドメイン名として `*.example.com` を作成できません。  
アカウント A とアカウント B の所有者が同じである場合は、[AWS サポートセンター](https://console.aws.amazon.com/support/home#/)に連絡して例外をリクエストできます。

## カスタムドメイン名に関する次のステップ
<a name="websocket-api-custom-domain-names-next-steps"></a>

HTTP API のカスタムドメイン名を設定するには、「API Gateway 開発者ガイド」の「REST API」セクションの説明に従います。

まず、カスタムドメイン名の証明書を指定します。詳細については、「[AWS Certificate Manager で証明書を準備する](how-to-specify-certificate-for-custom-domain-name.md)」を参照してください。次に、リージョン別カスタムドメイン名を作成します。詳細については、「[API Gateway でリージョン別カスタムドメイン名を設定する](apigateway-regional-api-custom-domain-create.md)」を参照してください。

# WebSocket API のカスタムドメイン名に API ステージをマッピングする
<a name="websocket-api-mappings"></a>

API マッピングを使用して、API ステージをカスタムドメイン名に接続します。ドメイン名を作成し、DNS レコードを設定したら、API マッピングを使用して、カスタムドメイン名を使用して API にトラフィックを送信します。

API マッピングは、API、ステージ、およびオプションでマッピングに使用するパスを指定します。たとえば、API の `production` ステージを `wss://api.example.com/orders` にマッピングできます。

API マッピングを作成する前に、API、ステージ、およびカスタムドメイン名が必要です。カスタムドメイン名の作成と設定の詳細については、「[API Gateway でリージョン別カスタムドメイン名を設定する](apigateway-regional-api-custom-domain-create.md)」を参照してください。

## 制限事項
<a name="websocket-api-mappings-restrictions"></a>
+ API マッピングでは、カスタムドメイン名とマップされた API が同じ AWS アカウントにある必要があります。
+ API マッピングに含めることができるのは、文字、数字、および `$-_.+!*'()` の文字だけです。
+ API マッピングのパスの最大文字数は 300 文字です。
+ WebSocket API を HTTP API または REST API と同じカスタムドメイン名にマッピングすることはできません。
+ 複数レベルの API マッピングを作成する場合、API Gateway はすべてのヘッダー名を小文字に変換します。

## API マッピングを作成する
<a name="websocket-api-mappings-examples"></a>

API マッピングを作成するには、最初にカスタムドメイン名、API、およびステージを作成する必要があります。カスタムドメイン名の作成方法については、「[API Gateway でリージョン別カスタムドメイン名を設定する](apigateway-regional-api-custom-domain-create.md)」を参照してください。

------
#### [ AWS マネジメントコンソール ]

**API マッピングを作成するには**

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

1. [**カスタムドメイン名**] を選択します。

1. 既に作成したカスタムドメイン名を選択します。

1. [**API マッピング**] を選択します。

1. [**Configure API mappings (API マッピングの設定)**] を選択します。

1. [**Add new mapping (新しいマッピングを追加)**] を選択します。

1. **API**、**Stage**、必要に応じて **Path** を入力します。

1. **[保存]** を選択します。

------
#### [ AWS CLI ]

次の [create-api-mapping](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api-mapping.html) コマンドは、API マッピングを作成します。この例では、API Gateway が指定された API およびステージに `api.example.com/v1` に対するリクエストを送信します。

```
aws apigatewayv2 create-api-mapping \
    --domain-name api.example.com \
    --api-mapping-key v1 \
    --api-id a1b2c3d4 \
    --stage test
```

------
#### [ CloudFormation ]

次の CloudFormation 例は、API マッピングを作成します。

```
MyApiMapping:
  Type: 'AWS::ApiGatewayV2::ApiMapping'
  Properties:
    DomainName: api.example.com
    ApiMappingKey: 'v1'
    ApiId: !Ref MyApi
    Stage: !Ref MyStage
```

------

# WebSocket APIs のカスタムドメイン名の IP アドレスタイプ
<a name="websocket-api-custom-domain-names-ip-address-type"></a>

カスタムドメイン名を作成する場合、ドメインを呼び出すことができる IP アドレスのタイプを指定します。IPv4 を選択すると、IPv4 アドレスを解決してドメインを呼び出すことができます。デュアルスタックを選択すると、IPv4 アドレスと IPv6 アドレスの両方を指定してドメインを呼び出すことができます。IP アドレスタイプをデュアルスタックに設定して、IP スペースの枯渇の問題を軽減したり、セキュリティ体制を強化したりすることをお勧めします。デュアルスタック IP アドレスタイプの利点の詳細については、「[IPv6 on AWS](https://docs.aws.amazon.com/whitepapers/latest/ipv6-on-aws/internet-protocol-version-6.html)」を参照してください。

## IP アドレスタイプに関する考慮事項
<a name="websocket-api-custom-domain-names-ip-address-type-considerations"></a>

以下の考慮事項は、IP アドレスタイプの使用に影響する可能性があります。
+ API Gateway カスタムドメイン名のデフォルトの IP アドレスタイプは IPv4 です。
+ カスタムドメイン名には、マッピングされたすべての API で同じ IP アドレスタイプを使用する必要はありません。デフォルトの API エンドポイントを無効にすると、発信者が API を呼び出す方法が影響を受ける可能性があります。

## カスタムドメイン名の IP アドレスタイプを変更する
<a name="websocket-api-custom-domain-names-ip-address-type-change"></a>

IP アドレスタイプは、ドメイン名のエンドポイント設定を更新して、変更できます。エンドポイント設定は、AWS マネジメントコンソール、AWS CLI、CloudFormation、または AWS SDK を使用して、更新できます。

------
#### [ AWS マネジメントコンソール ]

**カスタムドメイン名の IP アドレスタイプを変更するには**

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

1. パブリックカスタムドメイン名を選択します。

1. **[エンドポイント設定]** を選択します。

1. [IP アドレスタイプ] で、**[IPv4]** または **[デュアルスタック]** を選択します。

1. **[保存]** を選択します。

------
#### [ AWS CLI ]

次の [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-domain-name.html) コマンドは、IP アドレスタイプがデュアルスタックになるように API を更新します。

```
aws apigatewayv2 update-domain-name \
   --domain-name dualstack.example.com \
   --domain-name-configurations CertificateArn=arn:aws:acm:us-east-1:111122223333:certificate/abcd1234-5678-abc,IpAddressType=dualstack
```

出力は次のようになります。

```
{
    "ApiMappingSelectionExpression": "$request.basepath",
    "DomainName": "dualstack.example.com",
    "DomainNameConfigurations": [
        {
            "ApiGatewayDomainName": "d-abcd1234.execute-api.us-east-1.amazonaws.com",
            "CertificateArn": "arn:aws:acm:us-east-1:111122223333:certificate/abcd1234-5678-abc",
            "DomainNameStatus": "AVAILABLE",
            "EndpointType": "REGIONAL",
            "HostedZoneId": "Z3LQWSYCGH4ADY",
            "SecurityPolicy": "TLS_1_2",
            "IpAddressType": "dualstack"
        }
    ],
    "Tags": {}
}
```

------

# WebSocket API のデフォルトのエンドポイントを無効にする
<a name="websocket-api-disable-default-endpoint"></a>

デフォルトでは、クライアントは、API Gateway が API 用に生成する `execute-api` エンドポイントを使用して API を呼び出すことができます。クライアントがカスタムドメイン名を使用した場合のみ API にアクセスできるようにするには、デフォルトの `execute-api` エンドポイントを無効にします。デフォルトのエンドポイントを無効にすると、API のすべてのステージに影響します。

次の手順は、WebSocket API のデフォルトのエンドポイントを無効にする方法を示しています。

------
#### [ AWS マネジメントコンソール ]

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

1. WebSocket API を選択します。

1. **[API 設定]** を選択します。

1. **[API の詳細]** で、**[編集]** を選択します。

1. **[デフォルトのエンドポイント]** で、**[非アクティブ]** を選択します。

1. [**Save changes**] (変更の保存) をクリックします。

1. メインナビゲーションペインで、**[ルート]** を選択します。

1. **[デプロイ]** を選択して API を再デプロイするか、新しいステージを作成して変更を有効にします。

------
#### [ AWS CLI ]

次の [update-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-api.html) コマンドは、WebSocket API のデフォルトエンドポイントを無効にします。

```
aws apigatewayv2 update-api \
    --api-id abcdef123 \
    --disable-execute-api-endpoint
```

デフォルトのエンドポイントを無効にした後で、変更を有効にするには、API をデプロイする必要があります。

次の AWS CLI コマンドは、デプロイを作成します。

```
aws apigatewayv2 create-deployment \
    --api-id abcdef123 \
    --stage-name dev
```

------

# API Gateway で WebSocket API を保護する
<a name="websocket-api-protect"></a>

API Gateway は、悪意のあるユーザーやトラフィックの急増など、特定の脅威から API を保護するさまざまな方法を提供します。SSL 証明書の生成やスロットリングターゲットの設定などの戦略を使用して API を保護できます。SSL 証明書の生成の詳細については、「[API Gateway のバックエンド認証用 SSL 証明書の生成と設定](getting-started-client-side-ssl-authentication.md)」を参照してください。このセクションの残りの部分では、スロットリングターゲットの設定について説明します。

API のスロットリングを設定して、多すぎるリクエストで API の負荷が高くなりすぎないように保護できます。スロットルはベストエフォートベースで適用されるため、これらは保証されたリクエスト上限ではなく、目標として考える必要があります。

API Gateway は、トークンバケットアルゴリズムを使用してトークンでリクエストをカウントし、API へのリクエストを調整します。特に API Gateway では、アカウントのすべての API に送信されるリクエストのレートとバーストをリージョンごとに検証します。トークンバケットアルゴリズムでは、これらの制限の事前定義されたオーバーランがバーストによって許可されますが、場合によっては、他の要因によって制限のオーバーランが発生することがあります。

リクエストの送信数がリクエストの定常レートおよびバーストを超えると、API Gateway はリクエストを調整を開始します。クライアントは、この時点で `429 Too Many Requests` エラーレスポンスを受け取ることがあります。このような例外をキャッチすると、クライアントは失敗したリクエストをレート制限する方法で再送信できます。

API デベロッパーは、API の個々のステージまたはルートに制限を設定して、アカウントのすべての API にわたるパフォーマンス全体を向上させることができます。

## リージョンごとのアカウントレベルのスロットリング
<a name="websocket-api-protect-throttling-account"></a>

API Gateway はデフォルトで、リージョンごとに AWS アカウント内のすべての API 全体で定常状態のリクエスト/秒 (RPS) を制限します。また、リージョンごとに AWS アカウント内のすべての API にわたってバースト (最大バケットサイズ) を制限します。API Gateway では、バースト制限は、API Gateway が `429 Too Many Requests` エラーレスポンスを返す前に処理する同時リクエスト送信の目標最大数を表します。スロットリングクォータの詳細については、「[Amazon API Gateway のクォータ](limits.md)」を参照してください。

アカウントごとの制限は、指定したリージョンのアカウント内のすべての API に適用されます。このアカウントレベルのレート制限は、申請に応じて引き上げることができます。API のタイムアウトが短く、ペイロードが小さい場合、高い制限を設定できます。リージョンごとのアカウントレベルのスロットリング制限の引き上げを申請するには、[AWS サポートセンター](https://console.aws.amazon.com/support/home#/)にお問い合わせください。詳細については、「[Amazon API Gateway のクォータ](limits.md)」を参照してください。これらの制限は、AWS スロットリングの制限以上に高くすることはできません。

## ルートレベルのスロットリング
<a name="websocket-api-protect-throttling-route"></a>

特定のステージでまたは API の個々のルートでアカウントレベルのリクエストスロットリング制限を上書きするように、ルートレベルのスロットリングを設定できます。デフォルトのルートスロットリング制限は、アカウントレベルのレート制限を超えることはできません。

AWS CLI を使用して、ルートレベルのスロットリングを設定できます。次の [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-stage.html) コマンドは、API の指定されたステージとルートのカスタムスロットリングを設定します。

```
aws apigatewayv2 update-stage \
    --api-id a1b2c3d4 \
    --stage-name dev \
    --route-settings '{"messages":{"ThrottlingBurstLimit":100,"ThrottlingRateLimit":2000}}'
```

# API Gateway で WebSocket API をモニタリングする
<a name="websocket-api-monitor"></a>

CloudWatch メトリクスと CloudWatch Logs を使用して、WebSocket API をモニタリングできます。ログとメトリクスを組み合わせることで、エラーをログに記録し、API のパフォーマンスを監視できます。

**注記**  
API Gateway は、次の場合にログとメトリクスが生成されない可能性があります。  
413 Request Entity Too Large エラー
過剰な 429 Too Many Requests エラー
API マッピングを持たないカスタムドメインに送信されたリクエストからの 400 シリーズのエラー
内部の障害によって発生した 500 シリーズのエラー

**Topics**
+ [CloudWatch メトリクスを使用して WebSocket API の実行をモニタリングする](apigateway-websocket-api-logging.md)
+ [API Gateway で WebSocket API のログ記録を設定する](websocket-api-logging.md)

# CloudWatch メトリクスを使用して WebSocket API の実行をモニタリングする
<a name="apigateway-websocket-api-logging"></a>

[Amazon CloudWatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html) メトリクスを使用して、WebSocket API をモニタリングできます。この設定は、REST API に使用される設定と似ています。詳細については、「[Amazon CloudWatch のメトリクスを使用して REST API の実行をモニタリングする](monitoring-cloudwatch.md)」を参照してください。

WebSocket API では、次のメトリクスがサポートされています。


| メトリクス | 説明 | 
| --- | --- | 
| ConnectCount | \$1connect ルート統合に送信されるメッセージの数。 | 
| MessageCount | クライアントとの間で送受信される、WebSocket API に送信されるメッセージの数。 | 
| IntegrationError | 統合から 4XX/5XX レスポンスを返すリクエストの数。 | 
| ClientError | 統合が呼び出される前に API Gateway によって返された 4XX レスポンスを持つリクエストの数。 | 
| ExecutionError | 統合を呼び出す際に発生したエラー。 | 
| IntegrationLatency | API Gateway による統合へのリクエストの送信から、API Gateway による統合からのレスポンスの受信までの時間の差。コールバックと Mock 統合では除外されます。 | 

API Gateway のメトリクスをフィルタリングするには、次の表のディメンションを使用できます。


| ディメンション | 説明 | 
| --- | --- | 
| ApiId | 指定した API ID で API の API Gateway メトリクスをフィルタリングします。 | 
| ApiId、ステージ | 指定した API ID とステージ ID で API ステージの API Gateway メトリクスをフィルタリングします。 | 
| ApiId、メソッド、リソース、ステージ |  指定した API ID、ステージ ID、リソースパス、ルート ID で API メソッドの API Gateway メトリクスをフィルタリングします。 詳細な CloudWatch のメトリクスを明示的に有効にしない限り、API Gateway はこれらのメトリクスを送信しません。そのためには、API Gateway V2 REST API の [UpdateStage](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-stages-stagename.html) アクションを呼び出して、`detailedMetricsEnabled` プロパティを `true` に更新します。[update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-stage.html) AWS CLI コマンドを呼び出して `DetailedMetricsEnabled` プロパティを `true` に更新することもできます。このようなメトリクスを有効にすることで、アカウントに追加料金が発生します。詳細については、[Amazon CloudWatch 料金表](https://aws.amazon.com/cloudwatch/pricing/)をご覧ください。  | 

# API Gateway で WebSocket API のログ記録を設定する
<a name="websocket-api-logging"></a>

ログ記録を有効にして CloudWatch Logs にログを記録することができます。CloudWatch による API のログには、実行ログとアクセスログの 2 種類があります。実行ログでは、API Gateway によって CloudWatch Logs が管理されます。このプロセスには、ロググループとログストリームの作成、および呼び出し元のリクエストとレスポンスのログストリームへのレポートが含まれます。

セキュリティ体制を向上させるには、`ERROR` または `INFO` レベルで実行ログを使用することをお勧めします。これは、さまざまなコンプライアンスフレームワークに準拠するために必要になる場合があります。詳細については、*AWS Security Hub ユーザーガイド*の「[Amazon API Gateway のコントロール](https://docs.aws.amazon.com/securityhub/latest/userguide/apigateway-controls.html)」を参照してください。

アクセスログの作成では、API デベロッパーとして、API にアクセスしたユーザーと、呼び出し元が API にアクセスした方法を記録します。独自のロググループを作成したり、既存のロググループを選択したりすることができます。これらは、API Gateway で管理することができます。アクセスの詳細を指定するには、`$context` 変数 (選択した形式で表示される) を選択し、ロググループを宛先として選択します。

CloudWatch ログ記録の設定方法については、「[API Gateway コンソールを使用した CloudWatch による API のログの設定](set-up-logging.md#set-up-access-logging-using-console)」を参照してください。

[**ログの形式**] を指定する際に、記録するコンテキスト変数を選択できます。次の変数は、サポートされています。


| パラメータ | 説明 | 
| --- | --- | 
| \$1context.apiId |  API Gateway が API に割り当てる識別子。  | 
| \$1context.authorize.error | 認可エラーメッセージ。 | 
| \$1context.authorize.latency | 認可レイテンシー (ミリ秒単位)。 | 
| \$1context.authorize.status | 認可の試行から返されたステータスコード。 | 
| \$1context.authorizer.error | オーソライザーから返されたエラーメッセージ。 | 
| \$1context.authorizer.integrationLatency | Lambda オーソライザーレイテンシー (ミリ秒)。 | 
| \$1context.authorizer.integrationStatus | オーソライザーから返されたステータスコード。 | 
| \$1context.authorizer.latency | オーソライザーのレイテンシー (ミリ秒単位)。 | 
| \$1context.authorizer.requestId | AWS エンドポイントのリクエスト ID | 
| \$1context.authorizer.status | オーソライザーから返されたステータスコード。 | 
| \$1context.authorizer.principalId |  クライアントにより送信され、API Gateway Lambda オーソライザー Lambda 関数から返されたトークンと関連付けられたプリンシパルユーザー ID (Lambda オーソライザーは、以前はカスタムオーソライザーと呼ばれていました)。  | 
| \$1context.authorizer.property |  API Gateway Lambda オーソライザーの関数から返された `context` マップの指定されたキー/値ペアの文字列化された値。たとえば、オーソライザーが次の `context` マップを返すとします。 <pre>"context" : {<br />                            "key": "value",<br />                            "numKey": 1,<br />                            "boolKey": true<br />                            }</pre> `$context.authorizer.key` の呼び出しでは `"value"` 文字列が返され、`$context.authorizer.numKey` の呼び出しでは `"1"` 文字列が返され、`$context.authorizer.boolKey` の呼び出しでは `"true"` 文字列が返されます。  | 
| \$1context.authenticate.error | 認証の試行から返されたエラーメッセージ。 | 
| \$1context.authenticate.latency | 認証レイテンシー (ミリ秒単位)。 | 
| \$1context.authenticate.status | 認証の試行から返されたステータスコード。 | 
| \$1context.connectedAt |  [エポック](https://en.wikipedia.org/wiki/Unix_time)形式の接続時間。  | 
| \$1context.connectionId |  クライアントへのコールバックを行うために使用できる接続の一意の ID。  | 
| \$1context.domainName |  WebSocket API のドメイン名。これは、(ハードコーディングされた値の代わりに) クライアントへのコールバックを行うために使用できます。  | 
| \$1context.error.message |  API Gateway エラーメッセージを含む文字列。  | 
| \$1context.error.messageString | \$1context.error.message を引用符で囲んだ値、つまり "\$1context.error.message"。 | 
| \$1context.error.responseType |  エラーのレスポンスタイプ。  | 
| \$1context.error.validationErrorString |  詳細な検証エラーメッセージを含む文字列。  | 
| \$1context.eventType |  イベントタイプ: (`CONNECT`、`MESSAGE`、または `DISCONNECT`)。  | 
| \$1context.extendedRequestId | \$1context.requestId と同等です。 | 
| \$1context.identity.accountId |  リクエストに関連付けられた AWS アカウント ID です。  | 
| \$1context.identity.apiKey |  キー対応 API リクエストに関連付けられた API 所有者キー。  | 
| \$1context.identity.apiKeyId | キー対応 API リクエストに関連付けられた API キー ID。 | 
| \$1context.identity.caller |  リクエストに署名した発信者のプリンシパル ID。IAM 認可を使用するルートでサポートされています。  | 
| \$1context.identity.cognitoAuthenticationProvider |  リクエスト元の発信者が使用するすべての Amazon Cognito 認証プロバイダーのカンマ区切りのリスト。リクエストが Amazon Cognito 認証情報で署名されている場合にのみ使用できます。 たとえば、Amazon Cognito ユーザープールのアイデンティティの場合、`cognito-idp. region.amazonaws.com/user_pool_id,cognito-idp.region.amazonaws.com/user_pool_id:CognitoSignIn:token subject claim` 利用可能な Amazon Cognito 認証プロバイダーについては、「Amazon Cognito 開発者ガイド」の「[フェデレーティッド ID の使用](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html)」を参照してください。** | 
| \$1context.identity.cognitoAuthenticationType |  リクエストを行う発信者の Amazon Cognito 認証タイプ。リクエストが Amazon Cognito 認証情報で署名されている場合にのみ使用できます。有効な値は、認証されたアイデンティティ`authenticated`および認証されていないアイデンティティ`unauthenticated`です。 | 
| \$1context.identity.cognitoIdentityId |  リクエストを行う発信者の Amazon Cognito ID。リクエストが Amazon Cognito 認証情報で署名されている場合にのみ使用できます。  | 
| \$1context.identity.cognitoIdentityPoolId |  リクエストを行う発信者の Amazon Cognito ID プール ID。リクエストが Amazon Cognito 認証情報で署名されている場合にのみ使用できます。  | 
| \$1context.identity.principalOrgId |  [AWS 組織 ID](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_org_details.html)。IAM 認可を使用するルートでサポートされています。  | 
| \$1context.identity.sourceIp |  API Gateway へのリクエストを実行する TCP 接続のソース IP アドレス。  | 
| \$1context.identity.user |  リソースアクセスに対して許可されるユーザーのプリンシパル識別子。IAM 認可を使用するルートでサポートされています。  | 
| \$1context.identity.userAgent |  API 発信者のユーザーエージェント。  | 
| \$1context.identity.userArn |  認証後に識別された有効ユーザーの Amazon リソースネーム (ARN) です。  | 
| \$1context.integration.error | 統合から返されたエラーメッセージ。 | 
| \$1context.integration.integrationStatus | Lambda プロキシ統合の場合、バックエンドの Lambda 関数コードからではなく、AWS Lambda から返されるステータスコード。 | 
| \$1context.integration.latency | 統合レイテンシー (ミリ秒)。これは \$1context.integrationLatency と同等です。 | 
| \$1context.integration.requestId | AWS エンドポイントのリクエスト ID これは \$1context.awsEndpointRequestId と同等です。 | 
| \$1context.integration.status | 統合から返されたステータスコード。Lambda プロキシ統合では、これは Lambda 関数コードから返されたステータスコードです。これは \$1context.integrationStatus と同等です。 | 
| \$1context.integrationLatency | 統合レイテンシー (ミリ秒)。アクセスログ記録でのみ使用できます。 | 
| \$1context.messageId |  メッセージの一意のサーバー側 ID。`$context.eventType` が `MESSAGE` である場合のみ利用できます。  | 
| \$1context.requestId |  `$context.extendedRequestId` と同じ  | 
| \$1context.requestTime | [CLF](https://httpd.apache.org/docs/current/logs.html#common) 形式の要求時間 (dd/MMM/yyyy:HH:mm:ss \$1-hhmm)。 | 
| \$1context.requestTimeEpoch | [エポック](https://en.wikipedia.org/wiki/Unix_time)形式のリクエスト時間 (ミリ秒単位)。 | 
| \$1context.routeKey |  選択されたルートキー。  | 
| \$1context.stage |  API 呼び出しのデプロイステージ (Beta、Prod など) 。  | 
| \$1context.status |  レスポンスステータス。  | 
| \$1context.waf.error |  から返されたエラーメッセージAWS WAF | 
| \$1context.waf.latency | AWS WAF レイテンシー (ミリ秒単位)。 | 
| \$1context.waf.status |  から返されたステータスコードAWS WAF | 

API Gateway コンソールには、一般的に使用されるアクセスログの形式の例が表示されます。以下にもその例を示します。
+ `CLF` ([Common Log Format](https://httpd.apache.org/docs/current/logs.html#common)):

  ```
  $context.identity.sourceIp $context.identity.caller \
  $context.identity.user [$context.requestTime] "$context.eventType $context.routeKey $context.connectionId" \
  $context.status $context.requestId
  ```

  継続文字 (`\`) は、視覚補助を目的としたものです。ログ形式は 1 行である必要があります。ログ形式の末尾に改行文字 (`\n`) を追加して、各ログエントリの末尾に改行を含めることができます。
+  `JSON`: 

  ```
  {
  "requestId":"$context.requestId", \
  "ip": "$context.identity.sourceIp", \
  "caller":"$context.identity.caller", \
  "user":"$context.identity.user", \
  "requestTime":"$context.requestTime", \
  "eventType":"$context.eventType", \
  "routeKey":"$context.routeKey", \
  "status":"$context.status", \
  "connectionId":"$context.connectionId"
  }
  ```

  継続文字 (`\`) は、視覚補助を目的としたものです。ログ形式は 1 行である必要があります。ログ形式の末尾に改行文字 (`\n`) を追加して、各ログエントリの末尾に改行を含めることができます。
+ `XML`: 

  ```
  <request id="$context.requestId"> \
   <ip>$context.identity.sourceIp</ip> \
   <caller>$context.identity.caller</caller> \
   <user>$context.identity.user</user> \
   <requestTime>$context.requestTime</requestTime> \
   <eventType>$context.eventType</eventType> \
   <routeKey>$context.routeKey</routeKey> \
   <status>$context.status</status> \
   <connectionId>$context.connectionId</connectionId> \
  </request>
  ```

  継続文字 (`\`) は、視覚補助を目的としたものです。ログ形式は 1 行である必要があります。ログ形式の末尾に改行文字 (`\n`) を追加して、各ログエントリの末尾に改行を含めることができます。
+ `CSV` (カンマ区切り値):

  ```
  $context.identity.sourceIp,$context.identity.caller, \
  $context.identity.user,$context.requestTime,$context.eventType, \
  $context.routeKey,$context.connectionId,$context.status, \
  $context.requestId
  ```

  継続文字 (`\`) は、視覚補助を目的としたものです。ログ形式は 1 行である必要があります。ログ形式の末尾に改行文字 (`\n`) を追加して、各ログエントリの末尾に改行を含めることができます。