

# API Gateway의 REST API 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)은 별도의 주제입니다. 요청 페이로드에 일치하는 모델 스키마가 없으면 패스스루를 선택하거나 원래 페이로드를 차단할 수 있습니다. 자세한 내용은 [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 객체는 Pet Store 예시의 샘플 데이터입니다.

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

데이터에는 반려동물의 `id`, `type` 및 `price`가 포함되어 있습니다. 이 데이터의 모델을 통해 다음을 수행할 수 있습니다.
+ 기본 요청 확인을 사용합니다.
+ 데이터 변환을 위한 매핑 템플릿을 생성합니다.
+ SDK를 생성할 때 사용자 정의 데이터 유형(UDT)을 생성합니다.

![\[PetStore API의 JSON 데이터 모델 예시입니다.\]](http://docs.aws.amazon.com/ko_kr/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\$117번째 줄에서 모델의 `properties`은 `id`, `type`, `price`입니다. 각 객체에는 모델에 설명된 속성이 있습니다.

1. 12번째 줄에서 `type` 객체에는 `dog`, `cat` 또는 `fish` 값만 있을 수 있습니다.

1. 14\$117번째 줄에서 `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` 모델이 `a1234` API의 `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를 생성할 때 데이터 모델과 함께 제공하면 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
    }
  }
}
```

이 모델에서는 `PetStoreOutputModel[i].description` 및 `PetStoreOutputModel[i].askingPrice` 속성을 읽음으로써 `description` 및 `askingPrice` 속성 값을 검색하도록 SDK를 호출할 수 있습니다. 모델이 제공되지 않는 경우, 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 요청에 대한 세 가지 검사기 중 하나를 선택하여 요청을 확인할 수 있습니다.
+ **본문을 확인합니다**.
+ **쿼리 문자열 파라미터 및 헤더를 확인합니다**.
+ **본문, 쿼리 문자열 파라미터 및 헤더를 확인합니다**.

 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 엔드포인트와 통합됩니다. 두 가지 유형의 요청 확인을 구성합니다.
+ `GET` 메서드에서 URL 쿼리 문자열 파라미터에 대한 요청 확인을 구성합니다.
+ `POST` 메서드에서 요청 본문에 대한 요청 확인을 구성합니다.

 이렇게 하면 특정 API 호출만 API로 전달될 수 있습니다.

[CloudFormation용 앱 생성 템플릿](samples/request-validation-tutorial-console.zip)을 다운로드하고 압축을 해제합니다. 이 템플릿을 사용하여 불완전한 API를 만들 수 있습니다. API Gateway 콘솔에서 나머지 단계를 완료하게 됩니다.

**CloudFormation 스택을 생성하려면**

1. CloudFormation 콘솔([https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/))을 엽니다.

1. **스택 생성**을 선택한 다음 **새 리소스 사용(표준)**을 선택합니다.

1. **템플릿 지정**에서 **템플릿 파일 업로드**를 선택합니다.

1. 다운로드한 템플릿을 선택합니다.

1. **다음**을 선택합니다.

1. **스택 이름**에 **request-validation-tutorial-console**을 입력하고 **다음**을 선택합니다.

1. **스택 옵션 구성**에서 **다음**을 선택합니다.

1. **기능**의 경우 CloudFormation이 계정에 IAM 리소스를 생성할 수 있음을 확인합니다.

1. **다음**을 선택한 후 **제출**을 선택합니다.

CloudFormation은 템플릿에 지정된 리소스를 프로비저닝합니다. 리소스 프로비저닝을 완료하는 데 몇 분 정도 걸릴 수 있습니다. CloudFormation 스택 상태가 **CREATE\$1COMPLETE**인 경우 다음 단계로 넘어갈 준비가 된 것입니다.

**새로 생성한 API를 선택하는 방법**

1. 새로 생성한 **request-validation-tutorial-console** 스택을 선택합니다.

1. **리소스**를 선택합니다.

1. **물리적 ID**에서 API를 선택합니다. 이 링크는 API Gateway 콘솔로 연결됩니다.

`GET` 및 `POST` 메서드를 수정하기 전에 모델을 만들어야 합니다.

**모델을 생성하는 방법**

1. 수신 요청의 본문에서 요청 확인을 사용하려면 모델이 필요합니다. 모델을 생성하려면 기본 탐색 창에서 **모델**을 선택합니다.

1. **Create model**(모델 생성)을 선택합니다.

1. **이름**에 **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. **쿼리 문자열 추가(Add query string)**를 선택합니다.

   1. **이름**에 **petType**를 입력합니다.

   1. **필수**를 끕니다.

   1. **캐싱**을 꺼진 상태로 둡니다.

1. **저장**을 선택합니다.

1. **통합 요청** 탭의 **통합 요청 설정**에서 **편집**을 선택합니다.

1. **URL 쿼리 문자열 파라미터**에서 다음을 수행합니다.

   1. **쿼리 문자열 추가(Add query string)**를 선택합니다.

   1. **이름**에 **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`와 dog 목록이 반환됩니다.

   이 출력 데이터를 변환하는 방법에 대한 자세한 내용은 [데이터 매핑 자습서](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. **삭제**를 선택한 다음 해당 선택을 확인합니다.

### 다음 단계
<a name="next-steps-request-validation-tutorial"></a>
+ 출력 데이터를 변환하고 더 많은 데이터 매핑을 수행하는 방법에 대한 자세한 내용은 [데이터 매핑 자습서](set-up-data-transformations-in-api-gateway.md#mapping-example-console)를 참조하세요.
+ AWS CLI를 사용하여 유사한 단계를 수행하려면 [AWS CLI를 사용하여 기본 요청 확인 설정](#api-gateway-request-validation-setup-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 엔드포인트와 통합됩니다. 다음과 같은 두 가지 요청 검사를 구성합니다.
+ `GET` 메서드에서 URL 쿼리 문자열 파라미터를 확인하는 `params-only` 검사기를 생성합니다.
+ `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 통합 버전을 가져오려면 [Linux용 Windows Subsystem을 설치](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. 다음 명령을 사용하여 `/validate` 리소스에 `GET` HTTP 메서드를 추가합니다. 이 명령은 `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"
   ```

   다음 명령을 사용하여 `/validate` 리소스에 `POST` HTTP 메서드를 추가합니다. 이 명령은 `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>

 요청의 어느 부분을 확인할지 선택하기 위해 [x-amazon-apigateway-request-validators.requestValidator 객체](api-gateway-swagger-extensions-request-validators.requestValidator.md) 객체 세트를 [x-amazon-apigateway-request-validators 객체](api-gateway-swagger-extensions-request-validators.md) 맵에 지정하여 API 수준에서 요청 검사기를 선언할 수 있습니다. 예시 OpenAPI 정의에는 두 가지 검사기가 있습니다.
+ `RequestBodyModel` 데이터 모델을 사용하여 본문과 파라미터를 모두 확인하는 `all` 검사기

  `RequestBodyModel` 데이터 모델은 입력 JSON 객체가 `name`, `type` 및 `price` 속성을 포함할 것을 요구합니다. `name` 속성은 임의의 문자열이 될 수 있으며, `type`은 지정된 열거 필드(`["dog", "cat", "fish"]`) 중 하나여야 하고, `price`는 25\$1500 사이여야 합니다. `id` 파라미터는 필요하지 않습니다.
+ 파라미터만 확인하는 `param-only` 검사기

 API의 모든 메서드에 대해 요청 검사기를 활성화하려면 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` 모음에 pet을 추가하고, `GET` 메서드를 노출시켜 지정된 유형으로 pet을 쿼리합니다.

 두 개의 요청 검사기가 선언되어 있습니다.

**`GETValidator`**  
이 검사기는 `GET` 메서드에서 활성화됩니다. API Gateway는 이 검사기를 사용하여 필수 쿼리 파라미터(`q1`)가 수신 요청에 포함되었으며 공백이 아님을 확인할 수 있습니다.

**`POSTValidator`**  
이 검사기는 `POST` 메서드에서 활성화됩니다. API Gateway는 이 검사기를 사용하여 콘텐츠 유형이 `application/json`일 때 페이로드 요청 형식이 지정된 `RequestBodyModel`을 준수하는지 확인합니다. 일치하는 콘텐츠 유형이 없는 경우 요청 검증이 수행되지 않습니다. 콘텐츠 유형에 상관없이 동일한 모델을 사용하려면 `$default`를 지정합니다. `RequestBodyModel`에는 pet 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}'
```