

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

 統合リクエストを進める前に API リクエストの基本的な検証を実行するよう API Gateway を設定できます。検証に失敗した場合、API Gateway はすぐにリクエストに失敗して、400 個のエラーレスポンスを発信者に返し、CloudWatch Logs で検証結果を発行します。これによりバックエンドへの不必要な呼び出すが減少します。さらに重要な点として、アプリケーション固有の検証作業に集中することができます。リクエスト本文を検証するには、必要なリクエストパラメータが有効で null でないことを確認するか、より複雑なデータ検証用のモデルスキーマを指定します。

**Topics**
+ [API Gateway における基本的なリクエストの検証の概要](#api-gateway-request-validation-basic-definitions)
+ [REST API のデータモデル](models-mappings-models.md)
+ [API Gateway で基本的なリクエストの検証を設定する](api-gateway-request-validation-set-up.md)
+ [基本的なリクエスト検証を含むサンプル API の AWS CloudFormation テンプレート](api-gateway-request-validation-sample-cloudformation.md)

## API Gateway における基本的なリクエストの検証の概要
<a name="api-gateway-request-validation-basic-definitions"></a>

 基本的なリクエストの検証は API Gateway で処理できるため、ユーザーはバックエンドでのアプリケーション固有の検証に集中できます。検証のために、API Gateway は以下の条件のどちらかまたは両方を確認します。
+ 受信リクエストの URI、クエリ文字列、ヘッダーに必要なリクエストパラメータが含まれており、空白ではない。API Gateway はパラメータの存在のみをチェックし、タイプまたは形式はチェックしません。
+  該当するリクエストペイロードが、特定のコンテンツタイプのためのメソッドの[設定済みの JSON スキーマ](https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04)リクエストに準拠している。一致するコンテンツタイプが見つからない場合、リクエストの検証は実行されません。コンテンツタイプを問わず同じモデルを使用するには、データモデルのコンテンツタイプを `$default` に設定します。

検証を有効にするには、[リクエストの検証](https://docs.aws.amazon.com/apigateway/latest/api/API_RequestValidator.html)により検証ルールを指定し、この検証を API の[リクエストの検証のマップ](https://docs.aws.amazon.com/apigateway/latest/api/API_RequestValidator.html)に追加し、検証を個々の API メソッドに割り当てます。

**注記**  
リクエスト本文の検証と[API Gateway で REST API のマッピングテンプレートを使用しないペイロードのメソッドリクエストの動作](integration-passthrough-behaviors.md)は、2 つの異なるトピックです。リクエストペイロードと一致するモデルスキーマがない場合、元のペイロードをパススルーするかブロックするかを選択できます。詳細については、「[API Gateway で REST API のマッピングテンプレートを使用しないペイロードのメソッドリクエストの動作](integration-passthrough-behaviors.md)」を参照してください。

# REST API のデータモデル
<a name="models-mappings-models"></a>

API Gateway では、モデルはペイロードのデータ構造を定義します。API Gateway では、[JSON スキーマのドラフト 4](https://tools.ietf.org/html/draft-zyp-json-schema-04) を使用してモデルを定義します。次の JSON オブジェクトは、PetStore の例のサンプルデータです。

```
{
    "id": 1,
    "type": "dog",
    "price": 249.99
}
```

データには、ペットの `id`、`type`、`price` が含まれています。このデータのモデルにより、以下のことが可能になります。
+ 基本的なリクエストの検証を使用する。
+ データ変換用のマッピングテンプレートを作成する。
+ SDK を生成するときに、ユーザー定義データ型 (UDT) を作成する。

![\[PetStore API の JSON データモデルの例。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/how-to-validate-requests.png)


このモデルの内容は以下のとおりです。

1. `$schema` オブジェクトは、有効な JSON スキーマのバージョン識別子を表します。このスキーマは JSON スキーマのドラフト v4 です。

1. `title` オブジェクトは、人間が読めるモデルの識別子です。このタイトルは `PetStoreModel` です。

1.  `required` 検証キーワードには、基本的なリクエストの検証用の `type` と `price` が必要です。

1. モデルの `properties` は、`id`、`type`、`price` です。各オブジェクトには、モデルに記述されているプロパティがあります。

1. オブジェクト `type` は、値として `dog`、`cat`、`fish` のいずれかのみを持つことができます。

1. オブジェクト `price` は数値で、`minimum` が 25、`maximum` が 500 に制限されます。

## PetStore モデル
<a name="PetStore-model-text"></a>

```
1 {
2 "$schema": "http://json-schema.org/draft-04/schema#",
3  "title": "PetStoreModel",
4  "type" : "object",
5  "required" : [ "price", "type" ],
6  "properties" : {
7    "id" : {
8      "type" : "integer"
9    },
10    "type" : {
11      "type" : "string",
12      "enum" : [ "dog", "cat", "fish" ]
13    },
14    "price" : {
15      "type" : "number",
16      "minimum" : 25.0,
17      "maximum" : 500.0
18    }
19  }
20 }
```

このモデルの内容は以下のとおりです。

1. 2 行目で、`$schema` オブジェクトは有効な JSON スキーマのバージョン識別子を表します。このスキーマは JSON スキーマのドラフト v4 です。

1. 3 行目で、`title` オブジェクトは、人間が読めるモデルの識別子です。このタイトルは `PetStoreModel` です。

1.  5 行目で、`required` 検証キーワードには、基本的なリクエストの検証用の `type` と `price` が必要です。

1.  6～17 行目で、モデルの `properties` は `id`、`type`、`price` です。各オブジェクトには、モデルに記述されているプロパティがあります。

1. 12 行目で、オブジェクト `type` は値として `dog`、`cat`、`fish` のいずれかのみを持つことができます。

1. 14～17 行目で、オブジェクト `price` は数値で、`minimum` が 25、`maximum` が 500 に制限されます。

## より複雑なモデルの作成
<a name="api-gateway-request-validation-model-more-complex"></a>

 `$ref` プリミティブを使用すると、より長いモデルの再利用可能な定義を作成できます。例えば、`price` オブジェクトを記述する `definitions` セクションで、`Price` という定義を作成できます。`$ref` の値は `Price` 定義です。

```
{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "PetStoreModelReUsableRef",
  "required" : ["price", "type" ],
  "type" : "object",
  "properties" : {
    "id" : {
      "type" : "integer"
    },
    "type" : {
      "type" : "string",
      "enum" : [ "dog", "cat", "fish" ]
    },
    "price" : {
        "$ref": "#/definitions/Price"
    }
  },
  "definitions" : {
      "Price": {
        "type" : "number",
        "minimum" : 25.0,
        "maximum" : 500.0
            }
      }
}
```

外部モデルファイルで定義された別のモデルスキーマを参照することもできます。`$ref` プロパティの値をモデルの場所に設定します。次の例では、`Price` モデルは API `a1234` の `PetStorePrice` モデルに定義されています。

```
{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "PetStorePrice",
  "type": "number",
  "minimum": 25,
  "maximum": 500
}
```

より長いモデルは `PetStorePrice` モデルを参照できます。

```
{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "PetStoreModelReusableRefAPI",
  "required" : [ "price", "type" ],
  "type" : "object",
  "properties" : {
    "id" : {
      "type" : "integer"
    },
    "type" : {
      "type" : "string",
      "enum" : [ "dog", "cat", "fish" ]
    },
    "price" : {
        "$ref": "https://apigateway.amazonaws.com/restapis/a1234/models/PetStorePrice"
    }
  }
}
```

## 出力データモデルを使用する
<a name="api-gateway-request-validation-output-model"></a>

データを変換する場合、統合レスポンスでペイロードモデルを定義できます。ペイロードモデルは SDK を生成するときに使用できます。Java、Objective-C、Swift などの厳密に型指定された言語では、オブジェクトはユーザー定義データ型 (UDT) に対応します。SDK の生成時にデータモデルで UDT を指定すると、API Gateway は UDT を作成します。データ変換の詳細については、「[API Gateway での REST API のテンプレート変換のマッピング](models-mappings.md)」を参照してください。

以下は、統合レスポンスからの出力データの例です。

```
{
[
  {
    "description" : "Item 1 is a dog.",
    "askingPrice" : 249.99
  },
  {
    "description" : "Item 2 is a cat.",
    "askingPrice" : 124.99
  },
  {
    "description" : "Item 3 is a fish.",
    "askingPrice" : 0.99
  }
]
}
```

次の例は、出力データを記述するペイロードモデルです。

```
{
"$schema": "http://json-schema.org/draft-04/schema#",
  "title": "PetStoreOutputModel",
  "type" : "object",
  "required" : [ "description", "askingPrice" ],
  "properties" : {
    "description" : {
      "type" : "string"
    },
    "askingPrice" : {
      "type" : "number",
      "minimum" : 25.0,
      "maximum" : 500.0
    }
  }
}
```

このモデルでは、SDK を呼び出し、`PetStoreOutputModel[i].description` プロパティと `PetStoreOutputModel[i].askingPrice` プロパティを読み取ることで、`description` と `askingPrice` のプロパティ値を取得できます。モデルが指定されていない場合、API Gateway は空のモデルを使用してデフォルト UDT を作成します。

## 次のステップ
<a name="api-gateway-request-validation-model-next-steps"></a>
+ このセクションでは、このトピックで紹介した概念について理解を深めるために役立つリソースを紹介します。

  以下のリクエストの検証チュートリアルを参考にしてください。
  + [API Gateway コンソールを使用してリクエストの検証を設定する](api-gateway-request-validation-set-up.md#api-gateway-request-validation-setup-in-console)
  +  [AWS CLI を使用して基本的なリクエストの検証を設定する](api-gateway-request-validation-set-up.md#api-gateway-request-validation-setup-cli)
  +  [OpenAPI 定義を使用して基本的なリクエストの検証を設定する](api-gateway-request-validation-set-up.md#api-gateway-request-validation-setup-importing-swagger)
+  データ変換とマッピングテンプレートの詳細については、「[API Gateway での REST API のテンプレート変換のマッピング](models-mappings.md)」を参照してください。

# API Gateway で基本的なリクエストの検証を設定する
<a name="api-gateway-request-validation-set-up"></a>

 このセクションでは、コンソール、AWS CLI、OpenAPI 定義を使用して API Gateway のリクエストの検証を設定する方法を示します。

**Topics**
+ [API Gateway コンソールを使用してリクエストの検証を設定する](#api-gateway-request-validation-setup-in-console)
+ [AWS CLI を使用して基本的なリクエストの検証を設定する](#api-gateway-request-validation-setup-cli)
+ [OpenAPI 定義を使用して基本的なリクエストの検証を設定する](#api-gateway-request-validation-setup-importing-swagger)

## API Gateway コンソールを使用してリクエストの検証を設定する
<a name="api-gateway-request-validation-setup-in-console"></a>

 API Gateway コンソールで API リクエストの 3 つの検証から 1 つを選択して、リクエストを検証できます。
+ **本体の検証**。
+ **クエリ文字列パラメータとヘッダーの検証**。
+ **本文、クエリ文字列パラメータ、ヘッダーの検証**。

 上記のいずれかの検証を API メソッドに適用すると、API Gateway コンソールは検証を API の [RequestValidators](https://docs.aws.amazon.com/apigateway/latest/api/API_RequestValidator.html) マップに追加します。

このチュートリアルに従うには、CloudFormation テンプレートを使用して不完全な API Gateway API を作成します。この API には、`GET` メソッドと `POST` メソッドを持つ `/validator` リソースがあります。どちらのメソッドも `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP エンドポイントと統合されています。次の 2 種類のリクエストの検証を設定します。
+ `GET` メソッドでは、URL クエリ文字列パラメータに対するリクエストの検証を設定します。
+ `POST` メソッドでは、リクエスト本文に対するリクエストの検証を設定します。

 これにより、特定の API コールのみを API にパススルーできます。

[CloudFormation のアプリケーション作成テンプレート](samples/request-validation-tutorial-console.zip)をダウンロードして解凍します。このテンプレートを使用して不完全な API を作成します。残りのステップは API Gateway コンソールで完了します。

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

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

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

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

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

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

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

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

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

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

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

**新しく作成した API を選択するには**

1. 新しく作成した **request-validation-tutorial-console** スタックを選択します。

1. **[リソース]** をクリックします。

1. **[物理 ID]** で API を選択します。このリンクを使用して API Gateway コンソールに移動します。

`GET` メソッドと `POST` メソッドを変更する前に、モデルを作成する必要があります。

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

1. 受信リクエストの本文でリクエストの検証を使用するには、モデルが必要です。モデルを作成するには、メインナビゲーションペインで **[モデル]** を選択します。

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

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

1. **[コンテンツタイプ]** として、「**application/json**」と入力します。一致するコンテンツタイプが見つからない場合、リクエストの検証は実行されません。コンテンツタイプに関係なく同じモデルを使用するには、「**\$1default**」と入力します。

1. **[説明]** に、モデルの説明として「**My PetStore Model**」と入力します。

1. **[モデルスキーマ]** で、次のモデルをコードエディタに貼り付け、**[作成]** を選択します。

   ```
   {
     "type" : "object",
     "required" : [ "name", "price", "type" ],
     "properties" : {
       "id" : {
         "type" : "integer"
       },
       "type" : {
         "type" : "string",
         "enum" : [ "dog", "cat", "fish" ]
       },
       "name" : {
         "type" : "string"
       },
       "price" : {
         "type" : "number",
         "minimum" : 25.0,
         "maximum" : 500.0
       }
     }
   }
   ```

これらのモデルの詳細については、「[REST API のデータモデル](models-mappings-models.md)」を参照してください。

**`GET` メソッドのリクエスト検証を設定するには**

1. メインナビゲーションペインで **[リソース]**、**[GET]** メソッドの順に選択します。

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

1. **[リクエストの検証]** で、**[クエリ文字列パラメータおよびヘッダーを検証]** を選択します。

1. **[URL クエリ文字列パラメータ]** で、次の操作を行います。

   1. [**クエリ文字列の追加**] を選択します。

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

   1. **[必須]** をオンにします。

   1. **[キャッシュ]** はオフのままにします。

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

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

1. **[URL クエリ文字列パラメータ]** で、次の操作を行います。

   1. [**クエリ文字列の追加**] を選択します。

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

   1. **[マッピング元]** として「**method.request.querystring.petType**」と入力します。これは、**petType** をペットの種類にマッピングします。

      データマッピングの詳細については、[データマッピングチュートリアル](set-up-data-transformations-in-api-gateway.md#mapping-example-console)を参照してください。

   1. **[キャッシュ]** はオフのままにします。

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

**`GET` メソッドのリクエスト検証をテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[クエリ文字列]** に「**petType=dog**」と入力し、**[テスト]** を選択します。

1. メソッドテストが `200 OK` と犬のリストを返します。

   この出力データを変換する方法については、[データマッピングチュートリアル](set-up-data-transformations-in-api-gateway.md#mapping-example-console)を参照してください。

1. **petType=dog** を削除して **[テスト]** を選択します。

1.  メソッドテストは、`400` エラーを返し、次のエラーメッセージを表示します。

   ```
   {
     "message": "Missing required request parameters: [petType]"
   }
   ```

**`POST` メソッドのリクエスト検証を設定するには**

1. メインナビゲーションペインで、**[ステージ]**、**[POST]** メソッドの順に選択します。

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

1. **[リクエストの検証]** で **[本文を検証]** を選択します。

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

1. **[コンテンツタイプ]** に、「**application/json**」と入力します。一致するコンテンツタイプが見つからない場合、リクエストの検証は実行されません。コンテンツタイプに関係なく同じモデルを使用するには、「`$default`」と入力します。

    **[モデル]** で、**PetStoreModel** を選択します。

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

**`POST` メソッドのリクエスト検証をテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[リクエスト本文]** で、次の内容をコードエディタに貼り付けます。

   ```
   {
     "id": 2,
     "name": "Bella",
     "type": "dog",
     "price": 400
   }
   ```

    **[テスト]** を選択します。

1. メソッドテストは、`200 OK` と成功メッセージを返します。

1. **[リクエスト本文]** で、次の内容をコードエディタに貼り付けます。

   ```
   {
     "id": 2,
     "name": "Bella",
     "type": "dog",
     "price": 4000
   }
   ```

    **[テスト]** を選択します。

1.  メソッドテストは、`400` エラーを返し、次のエラーメッセージを表示します。

   ```
   {
    "message": "Invalid request body"
   }
   ```

    テストログの一番下に、無効なリクエスト本文の理由が表示されます。この場合、ペットの価格はモデルに指定されている上限を超えていました。

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

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

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

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

### 次のステップ
<a name="next-steps-request-validation-tutorial"></a>
+ 出力データを変換して、より多くのデータマッピングを実行する方法については、[データマッピングチュートリアル](set-up-data-transformations-in-api-gateway.md#mapping-example-console)を参照してください。
+ [AWS CLI を使用して基本的なリクエストの検証を設定する](#api-gateway-request-validation-setup-cli)チュートリアルに従い、AWS CLI を使用して同様の手順を実行します。

## AWS CLI を使用して基本的なリクエストの検証を設定する
<a name="api-gateway-request-validation-setup-cli"></a>

AWS CLI を使用してリクエストの検証を設定するための検証を作成できます。このチュートリアルに従うには、CloudFormation テンプレートを使用して不完全な API Gateway API を作成します。

**注記**  
これはコンソールチュートリアルと同じ CloudFormation テンプレートではありません。

 事前に公開されている `/validator` リソースを使用して `GET` メソッドと `POST` メソッドを作成します。どちらのメソッドも `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP エンドポイントと統合されます。次の 2 つのリクエストの検証を設定します。
+ `GET` メソッドでは、`params-only` 検証を作成して URL クエリ文字列パラメータを検証します。
+ `POST` メソッドでは、`body-only` 検証を作成してリクエスト本文を検証します。

 これにより、特定の API コールのみを API にパススルーできます。

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

[CloudFormation のアプリケーション作成テンプレート](samples/request-validation-tutorial-cli.zip)をダウンロードして解凍します。

次のチュートリアルを完了するには、[AWS Command Line Interface (AWS CLI) バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) が必要です。

コマンドが長い場合は、エスケープ文字 (`\`) を使用してコマンドを複数行に分割します。
**注記**  
Windows では、一般的に使用する Bash CLI コマンドの一部 (`zip` など) が、オペレーティングシステムの組み込みターミナルでサポートされていません。Ubuntu および Bash の Windows 統合バージョンを取得するには、[Windows Subsystem for Linux をインストール](https://learn.microsoft.com/en-us/windows/wsl/install)します。このガイドの CLI コマンドの例では、Linux フォーマットを使用しています。Windows CLI を使用している場合、インライン JSON ドキュメントを含むコマンドを再フォーマットする必要があります。

1.  次のコマンドを使用して CloudFormation スタックを作成します。

   ```
   aws cloudformation create-stack --stack-name request-validation-tutorial-cli --template-body file://request-validation-tutorial-cli.zip --capabilities CAPABILITY_NAMED_IAM 
   ```

1. CloudFormation は、テンプレートで指定されたリソースをプロビジョニングします。リソースのプロビジョニングには数分かかることがあります。次のコマンドを使用して CloudFormation スタックのステータスを確認します。

   ```
   aws cloudformation describe-stacks --stack-name request-validation-tutorial-cli
   ```

1. CloudFormation スタックのステータスが `StackStatus: "CREATE_COMPLETE"` になったら、次のコマンドを使用して関連する出力値を取得し、以後のステップで使用します。

   ```
    aws cloudformation describe-stacks --stack-name request-validation-tutorial-cli --query "Stacks[*].Outputs[*].{OutputKey: OutputKey, OutputValue: OutputValue, Description: Description}"
   ```

   出力値は以下のとおりです。
   + ApiId。API の ID です。このチュートリアルの場合、API ID は `abc123` です。
   + ResourceId。`GET` メソッドと `POST` メソッドが公開されている検証リソースの ID です。このチュートリアルの場合、リソース ID は `efg456` です。

**リクエストの検証を作成してモデルをインポートするには**

1. AWS CLI でリクエストの検証を行うには、検証が必要です。リクエストパラメータのみを検証する検証を作成するには、次のコマンドを使用します。

   ```
   aws apigateway create-request-validator --rest-api-id abc123 \
         --no-validate-request-body \
         --validate-request-parameters \
         --name params-only
   ```

   `params-only` 検証の ID をメモしておきます。

1.  リクエスト本文のみを検証する検証を作成するには、次のコマンドを使用します。

   ```
   aws apigateway create-request-validator --rest-api-id abc123 \
         --validate-request-body \
         --no-validate-request-parameters \
         --name body-only
   ```

   `body-only` 検証の ID をメモしておきます。

1.  受信リクエストの本文でリクエストの検証を行うには、モデルが必要です。モデルをインポートするには、以下のコマンドを使用します。

   ```
   aws apigateway create-model --rest-api-id abc123 --name PetStoreModel --description 'My PetStore Model' --content-type 'application/json' --schema '{"type": "object", "required" : [ "name", "price", "type" ], "properties" : { "id" : {"type" : "integer"},"type" : {"type" : "string", "enum" : [ "dog", "cat", "fish" ]},"name" : { "type" : "string"},"price" : {"type" : "number","minimum" : 25.0, "maximum" : 500.0}}}}' 
   ```

   一致するコンテンツタイプが見つからない場合、リクエストの検証は実行されません。コンテンツタイプに関係なく同じモデルを使用するには、キーとして `$default` を指定します。

**`GET` メソッドと `POST` メソッドを作成するには**

1. 次のコマンドを使用して、`GET` HTTP メソッドを `/validate` リソースに追加します。このコマンドは、`GET` メソッドを作成して、`params-only` 検証を追加し、必要に応じてクエリ文字列 `petType` を設定します。

   ```
   aws apigateway put-method --rest-api-id abc123 \
          --resource-id efg456 \
          --http-method GET \
          --authorization-type "NONE" \
          --request-validator-id aaa111 \
          --request-parameters "method.request.querystring.petType=true"
   ```

   次のコマンドを使用し、`POST` HTTP メソッドを `/validate` リソースに追加します。このコマンドは、`POST` メソッドを作成して、`body-only` 検証を追加し、モデルを本文専用の検証にアタッチします。

   ```
   aws apigateway put-method --rest-api-id abc123 \
          --resource-id efg456 \
          --http-method POST \
          --authorization-type "NONE" \
          --request-validator-id bbb222 \
          --request-models 'application/json'=PetStoreModel
   ```

1.  次のコマンドを使用して、`GET /validate` メソッドの `200 OK` レスポンスを設定します。

   ```
   aws apigateway put-method-response --rest-api-id abc123  \
               --resource-id efg456 \
               --http-method GET \
               --status-code 200
   ```

    次のコマンドを使用して、`POST /validate` メソッドの `200 OK` レスポンスを設定します。

   ```
   aws apigateway put-method-response --rest-api-id abc123  \
               --resource-id efg456 \
               --http-method POST \
               --status-code 200
   ```

1.  次のコマンドを使用して、`GET /validation` メソッドの指定された HTTP エンドポイントを `Integration` に設定します。

   ```
   aws apigateway put-integration --rest-api-id abc123  \
               --resource-id efg456 \
               --http-method GET \
               --type HTTP \
               --integration-http-method GET \
               --request-parameters '{"integration.request.querystring.type" : "method.request.querystring.petType"}' \
               --uri 'http://petstore-demo-endpoint.execute-api.com/petstore/pets'
   ```

    次のコマンドを使用して、`POST /validation` メソッドの指定された HTTP エンドポイントを `Integration` に設定します。

   ```
   aws apigateway put-integration --rest-api-id abc123  \
                 --resource-id efg456 \
                 --http-method POST \
                 --type HTTP \
                 --integration-http-method GET \
                 --uri 'http://petstore-demo-endpoint.execute-api.com/petstore/pets'
   ```

1.  次のコマンドを使用して、`GET /validation` メソッドの統合レスポンスを設定します。

   ```
   aws apigateway put-integration-response --rest-api-id abc123 \
                 --resource-id efg456\
                 --http-method GET \
                 --status-code 200 \
                 --selection-pattern ""
   ```

    次のコマンドを使用して、`POST /validation` メソッドの統合レスポンスを設定します。

   ```
   aws apigateway put-integration-response --rest-api-id abc123 \
               --resource-id efg456 \
               --http-method POST \
               --status-code 200 \
               --selection-pattern ""
   ```

**API をテストするには**

1. クエリ文字列に対するリクエストの検証を実行する `GET` メソッドをテストするには、次のコマンドを使用します。

   ```
   aws apigateway test-invoke-method --rest-api-id abc123 \
               --resource-id efg456 \
               --http-method GET \
               --path-with-query-string '/validate?petType=dog'
   ```

   結果として、`200 OK` と犬のリストが返されます。

1. 次のコマンドを使用して、クエリ文字列 `petType` を含めずにテストします。

   ```
   aws apigateway test-invoke-method --rest-api-id abc123 \
               --resource-id efg456 \
               --http-method GET
   ```

   結果として `400` エラーが返されます。

1. リクエスト本文に対するリクエストの検証を実行する `POST` メソッドをテストするには、次のコマンドを使用します。

   ```
    aws apigateway test-invoke-method --rest-api-id abc123 \
               --resource-id efg456 \
               --http-method POST \
               --body '{"id": 1, "name": "bella", "type": "dog", "price" : 400 }'
   ```

   結果として、`200 OK` と成功メッセージが返されます。

1. 次のコマンドを実行し、無効な本文を使用してテストします。

   ```
    aws apigateway test-invoke-method --rest-api-id abc123 \
                 --resource-id efg456 \
                 --http-method POST \
                 --body '{"id": 1, "name": "bella", "type": "dog", "price" : 1000 }'
   ```

   犬の価格がモデルで定義されている最大価格を超えているため、結果として `400` エラーが返されます。

**CloudFormation スタックを削除するには**
+ CloudFormation リソースを削除するには、次のコマンドを使用します。

  ```
  aws cloudformation delete-stack  --stack-name request-validation-tutorial-cli
  ```

## OpenAPI 定義を使用して基本的なリクエストの検証を設定する
<a name="api-gateway-request-validation-setup-importing-swagger"></a>

 API レベルでリクエストの検証を宣言するには、[x-amazon-apigateway-request-validators オブジェクト](api-gateway-swagger-extensions-request-validators.md) マップ内の [x-amazon-apigateway-request-validators.requestValidator オブジェクト](api-gateway-swagger-extensions-request-validators.requestValidator.md) オブジェクトのセットを指定して、リクエストのどの部分を検証するかを選択します。OpenAPI 定義の例では、次の 2 つの検証があります。
+ `all` 検証では、本文 (`RequestBodyModel` データモデルを使用) とパラメータの両方を検証します。

  `RequestBodyModel` データモデルでは、入力 JSON オブジェクトに `name`、`type`、`price` の各プロパティを含める必要があります。`name` プロパティは任意の文字列にすることができ、`type` は指定された列挙フィールド (`["dog", "cat", "fish"]`) のいずれかでなければなりません。また、`price` は 25 から 500 の範囲にする必要があります。`id` パラメータは必須ではありません。
+ `param-only` 検証では、パラメータのみを検証します。

 API のすべてのメソッドでリクエストの検証を有効にするには、OpenAPI 定義の API レベルで [x-amazon-apigateway-request-validator プロパティ](api-gateway-swagger-extensions-request-validator.md) プロパティを指定します。OpenAPI 定義の例の場合、`all` 検証は、オーバーライドされない限り、すべての API メソッドで使用されます。モデルを使用して本文を検証する際、一致するコンテンツタイプが見つからない場合、リクエストの検証は実行されません。コンテンツタイプに関係なく同じモデルを使用するには、キーとして `$default` を指定します。

個々のメソッドでリクエストの検証を有効にするには、メソッドレベルで `x-amazon-apigateway-request-validator` プロパティを指定します。OpenAPI 定義の例の場合、`param-only` 検証は `GET` メソッドの `all` 検証を上書きします。



OpenAPI のサンプルを API Gateway にインポートするには、[リージョン API を API Gateway にインポートする](import-export-api-endpoints.md) または [エッジ最適化 API を API Gateway にインポートする](import-edge-optimized-api.md) に対する次の手順を参照してください。

------
#### [ OpenAPI 3.0 ]

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "ReqValidators Sample",
    "version" : "1.0.0"
  },
  "servers" : [ {
    "url" : "/{basePath}",
    "variables" : {
      "basePath" : {
        "default" : "/v1"
      }
    }
  } ],
  "paths" : {
    "/validation" : {
      "get" : {
        "parameters" : [ {
          "name" : "q1",
          "in" : "query",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response",
            "headers" : {
              "test-method-response-header" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/ArrayOfError"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator" : "params-only",
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "400",
              "responseParameters" : {
                "method.response.header.test-method-response-header" : "'static value'"
              },
              "responseTemplates" : {
                "application/xml" : "xml 400 response template",
                "application/json" : "json 400 response template"
              }
            },
            "2\\d{2}" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.querystring.type" : "method.request.querystring.q1"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      },
      "post" : {
        "parameters" : [ {
          "name" : "h1",
          "in" : "header",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/RequestBodyModel"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "200 response",
            "headers" : {
              "test-method-response-header" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/ArrayOfError"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator" : "all",
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "POST",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "400",
              "responseParameters" : {
                "method.response.header.test-method-response-header" : "'static value'"
              },
              "responseTemplates" : {
                "application/xml" : "xml 400 response template",
                "application/json" : "json 400 response template"
              }
            },
            "2\\d{2}" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.custom_h1" : "method.request.header.h1"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "RequestBodyModel" : {
        "required" : [ "name", "price", "type" ],
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "integer"
          },
          "type" : {
            "type" : "string",
            "enum" : [ "dog", "cat", "fish" ]
          },
          "name" : {
            "type" : "string"
          },
          "price" : {
            "maximum" : 500.0,
            "minimum" : 25.0,
            "type" : "number"
          }
        }
      },
      "ArrayOfError" : {
        "type" : "array",
        "items" : {
          "$ref" : "#/components/schemas/Error"
        }
      },
      "Error" : {
        "type" : "object"
      }
    }
  },
  "x-amazon-apigateway-request-validators" : {
    "all" : {
      "validateRequestParameters" : true,
      "validateRequestBody" : true
    },
    "params-only" : {
      "validateRequestParameters" : true,
      "validateRequestBody" : false
    }
  }
}
```

------
#### [ OpenAPI 2.0 ]

```
{
  "swagger" : "2.0",
  "info" : {
    "version" : "1.0.0",
    "title" : "ReqValidators Sample"
  },
  "basePath" : "/v1",
  "schemes" : [ "https" ],
  "paths" : {
    "/validation" : {
      "get" : {
        "produces" : [ "application/json", "application/xml" ],
        "parameters" : [ {
          "name" : "q1",
          "in" : "query",
          "required" : true,
          "type" : "string"
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response",
            "schema" : {
              "$ref" : "#/definitions/ArrayOfError"
            },
            "headers" : {
              "test-method-response-header" : {
                "type" : "string"
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator" : "params-only",
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "400",
              "responseParameters" : {
                "method.response.header.test-method-response-header" : "'static value'"
              },
              "responseTemplates" : {
                "application/xml" : "xml 400 response template",
                "application/json" : "json 400 response template"
              }
            },
            "2\\d{2}" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.querystring.type" : "method.request.querystring.q1"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      },
      "post" : {
        "consumes" : [ "application/json" ],
        "produces" : [ "application/json", "application/xml" ],
        "parameters" : [ {
          "name" : "h1",
          "in" : "header",
          "required" : true,
          "type" : "string"
        }, {
          "in" : "body",
          "name" : "RequestBodyModel",
          "required" : true,
          "schema" : {
            "$ref" : "#/definitions/RequestBodyModel"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response",
            "schema" : {
              "$ref" : "#/definitions/ArrayOfError"
            },
            "headers" : {
              "test-method-response-header" : {
                "type" : "string"
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator" : "all",
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "POST",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "400",
              "responseParameters" : {
                "method.response.header.test-method-response-header" : "'static value'"
              },
              "responseTemplates" : {
                "application/xml" : "xml 400 response template",
                "application/json" : "json 400 response template"
              }
            },
            "2\\d{2}" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.custom_h1" : "method.request.header.h1"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  },
  "definitions" : {
    "RequestBodyModel" : {
      "type" : "object",
      "required" : [ "name", "price", "type" ],
      "properties" : {
        "id" : {
          "type" : "integer"
        },
        "type" : {
          "type" : "string",
          "enum" : [ "dog", "cat", "fish" ]
        },
        "name" : {
          "type" : "string"
        },
        "price" : {
          "type" : "number",
          "minimum" : 25.0,
          "maximum" : 500.0
        }
      }
    },
    "ArrayOfError" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/definitions/Error"
      }
    },
    "Error" : {
      "type" : "object"
    }
  },
  "x-amazon-apigateway-request-validators" : {
    "all" : {
      "validateRequestParameters" : true,
      "validateRequestBody" : true
    },
    "params-only" : {
      "validateRequestParameters" : true,
      "validateRequestBody" : false
    }
  }
}
```

------

# 基本的なリクエスト検証を含むサンプル API の AWS CloudFormation テンプレート
<a name="api-gateway-request-validation-sample-cloudformation"></a>

 以下の CloudFormation テンプレート定義の例は、リクエストの検証が有効なサンプル API を定義します。API は、[PetStore API](http://petstore-demo-endpoint.execute-api.com/petstore/pets) のサブセットです。`POST` メソッドを開示し、ペットを `pets` コレクションおよび `GET` メソッドに追加して、指定されたタイプによりペットのクエリを実行します。

 宣言されているリクエスト検証は 2 つあります。

**`GETValidator`**  
この検証は、`GET` メソッドで有効になります。この検証により、必須のクエリパラメータ (`q1`) が受信リクエストに含まれており、空白でないことを API Gateway が確認できるようになります。

**`POSTValidator`**  
この検証は、`POST` メソッドで有効になります。これにより、API Gateway は、コンテンツタイプが `application/json` のとき、ペイロードリクエスト形式が指定された `RequestBodyModel` に準拠していることを検証できます。一致するコンテンツタイプが見つからない場合、リクエストの検証は実行されません。コンテンツタイプに関係なく同じモデルを使用するには、`$default` を指定します。`RequestBodyModel` にはペット ID を定義する追加のモデル `RequestBodyModelId` が含まれています。

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  StageName:
    Type: String
    Default: v1
    Description: Name of API stage.
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: ReqValidatorsSample
  RequestBodyModelId:
    Type: 'AWS::ApiGateway::Model'
    Properties:
      RestApiId: !Ref Api
      ContentType: application/json
      Description: Request body model for Pet ID.
      Schema:
        $schema: 'http://json-schema.org/draft-04/schema#'
        title: RequestBodyModelId
        properties:
            id:
              type: integer
  RequestBodyModel: 
    Type: 'AWS::ApiGateway::Model'
    Properties:
      RestApiId: !Ref Api
      ContentType: application/json
      Description: Request body model for Pet type, name, price, and ID.
      Schema:
        $schema: 'http://json-schema.org/draft-04/schema#'
        title: RequestBodyModel
        required:
          - price
          - name
          - type
        type: object
        properties:
            id:
              "$ref": !Sub 
                - 'https://apigateway.amazonaws.com/restapis/${Api}/models/${RequestBodyModelId}'
                - Api: !Ref Api
                  RequestBodyModelId: !Ref RequestBodyModelId
            price: 
              type: number
              minimum: 25
              maximum: 500
            name:
              type: string
            type:
              type: string
              enum:
                - "dog"
                - "cat"
                - "fish"
  GETValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: params-only
      RestApiId: !Ref Api
      ValidateRequestBody: False
      ValidateRequestParameters: True 
  POSTValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: body-only
      RestApiId: !Ref Api
      ValidateRequestBody: True
      ValidateRequestParameters: False
  ValidationResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !GetAtt Api.RootResourceId
      PathPart: 'validation'
  ValidationMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref ValidationResource
      HttpMethod: GET
      AuthorizationType: NONE
      RequestValidatorId: !Ref GETValidator
      RequestParameters:
        method.request.querystring.q1: true
      Integration:
        Type: HTTP_PROXY
        IntegrationHttpMethod: GET
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/
  ValidationMethodPost:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref ValidationResource
      HttpMethod: POST
      AuthorizationType: NONE
      RequestValidatorId: !Ref POSTValidator
      RequestModels:
        application/json : !Ref RequestBodyModel 
      Integration:
        Type: HTTP_PROXY
        IntegrationHttpMethod: POST
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/
  ApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn:
      - ValidationMethodGet
      - RequestBodyModel 
    Properties:
      RestApiId: !Ref Api
      StageName: !Sub '${StageName}'
Outputs:
  ApiRootUrl:
    Description: Root Url of the API
    Value: !Sub 'https://${Api}.execute-api.${AWS::Region}.amazonaws.com/${StageName}'
```