

# 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` を含むエラーが表示される場合があります。