

# API Gateway에서 REST API에 대한 API 요청, 응답 파라미터, 상태 코드 재정의
<a name="apigateway-override-request-response-parameters"></a>

매핑 템플릿 변환을 사용하여 모든 유형의 요청 파라미터, 응답 헤더 또는 응답 상태 코드를 재정의할 수 있습니다. 매핑 템플릿을 사용하려면 다음과 같이 합니다.
+ 다대일 파라미터 매핑 수행
+ 표준 API Gateway 매핑이 적용된 후 파라미터 재정의
+ 본문 내용이나 기타 파라미터 값을 기반으로 파라미터를 조건부로 매핑
+ 프로그래밍 방식으로 새 파라미터 생성
+ 통합 엔드포인트에서 반환한 상태 코드 재정의

재정의는 최종입니다. 각 파라미터에 한 번만 재정의를 적용할 수 있습니다. 같은 파라미터에 여러 번 재정의를 시도하면 API Gateway에서 `5XX` 응답을 반환합니다. 템플릿에서 같은 파라미터를 여러 번 재정의해야 할 경우에는 변수를 하나 생성하여 템플릿 마지막에 재정의를 적용하는 것이 좋습니다. 전체 템플릿을 구문 분석한 후에만 템플릿이 적용됩니다.

## 예제 1: 통합 본문을 기반으로 상태 코드 재정의
<a name="apigateway-override-request-response-examples"></a>

다음 예제에서는 [예제 API](api-gateway-create-api-from-example.md)를 사용하여 통합 응답 본문을 기반으로 상태 코드를 재정의합니다.

------
#### [ AWS Management Console ]

**통합 응답 본문을 기반으로 상태 코드 재정의**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)에서 API Gateway 콘솔에 로그인합니다.

1. **API 생성**을 선택합니다.

1. **REST API**에서 **빌드**를 선택합니다.

1. **API 세부 정보**에서 **예제 API**를 선택합니다.

1. **API 생성**을 선택합니다.

   API Gateway는 예제 반려동물 저장소 API를 만듭니다. 반려동물에 대한 정보를 검색하려면 `GET /pets/{petId}`의 API 메서드 요청을 사용합니다. 여기서 `{petId}`는 반려동물의 ID 번호에 해당하는 경로 파라미터입니다.

   이 예제에서는 오류 조건을 탐지했을 때 `GET` 메서드의 응답 코드를 `400`으로 재정의합니다.

1. **리소스** 트리에서, `/{petId}` 아래의 `GET` 메서드를 선택합니다.

1. 먼저 API의 현재 구현을 테스트합니다.

   **테스트** 탭을 선택합니다. 탭을 표시하려면 오른쪽 화살표 버튼을 선택해야 할 수도 있습니다.

1. **petId**에 **-1**을 입력한 다음 **테스트**를 선택합니다.

   **응답 본문**은 범위를 벗어난 오류를 가리킵니다.

   ```
   {
     "errors": [
       {
         "key": "GetPetRequest.petId",
         "message": "The value is out of range."
       }
     ]
   }
   ```

   또한 **로그** 아래의 마지막 줄은 `Method completed with status: 200`으로 끝납니다.

   통합이 성공적으로 완료되었지만 오류가 발생했습니다. 이제 통합 응답을 기반으로 상태 코드를 재정의합니다.

1. **통합 응답** 탭의 **기본값 - 응답**에서 **편집**을 선택합니다.

1. **매핑 템플릿**을 선택합니다.

1. **매핑 템플릿 추가(Add mapping template)**를 선택합니다.

1. **콘텐츠 유형**에 **application/json**을 입력합니다.

1. **템플릿 본문**에 다음을 입력합니다.

   ```
   #set($inputRoot = $input.path('$'))
   $input.json("$")
   #if($inputRoot.toString().contains("error"))
   #set($context.responseOverride.status = 400)
   #end
   ```

   이 매핑 템플릿은 통합 응답에 `error` 문자열이 포함된 경우 `$context.responseOverride.status` 변수를 사용하여 상태 코드를 로 `400`으로 재정의합니다.

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

1. **테스트** 탭을 선택합니다.

1. **petId**에 **-1**을 입력합니다.

1. 결과에서 **응답 본문(Response Body)**은 범위 밖 오류를 가리킵니다.

   ```
   {
     "errors": [
       {
         "key": "GetPetRequest.petId",
         "message": "The value is out of range."
       }
     ]
   }
   ```

   그러나 **로그** 아래의 마지막 줄은 이제 `Method completed with status: 400`으로 끝납니다.

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

 이 예제에서는 [본문](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) 속성을 사용하여 OpenAPI 정의 파일을 API Gateway로 가져옵니다.

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body: 
        openapi: 3.0.1
        info:
          title: PetStore Example 1
          description: Example pet store API.
          version: "2025-01-14T00:13:18Z"
        paths:
          /pets/{petId}:
            get:
              parameters:
                - name: petId
                  in: path
                  required: true
                  schema:
                    type: string
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets/{petId}
                responses:
                  default:
                    statusCode: "200"
                    responseTemplates:
                      application/json: |-
                        #set($inputRoot = $input.path('$'))
                        $input.json("$")
                        #if($inputRoot.toString().contains("error"))
                        #set($context.responseOverride.status = 400)
                        #end
                requestParameters:
                  integration.request.path.petId: method.request.path.petId
                passthroughBehavior: when_no_match
                type: http
        components:
          schemas:
            Pet:
              type: object
              properties:
                id:
                  type: integer
                type:
                  type: string
                price:
                  type: number
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  ApiGatewayDeployment20250219:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  Stage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
       DeploymentId: !Ref ApiGatewayDeployment20250219
       RestApiId: !Ref Api
       StageName: prod
```

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

다음 OpenAPI 정의는 `GET pets/{petId}` 리소스를 만들고 통합 본문을 기반으로 상태 코드를 재정의합니다.

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "PetStore Example 1",
    "description" : "Example pet store API.",
    "version" : "2025-01-14T00:13:18Z"
  },
  "paths" : {
    "/pets/{petId}" : {
      "get" : {
        "parameters" : [ {
          "name" : "petId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets/{petId}",
          "responses" : {
            "default" : {
              "statusCode" : "200",
              "responseTemplates" : {
                "application/json" : "#set($inputRoot = $input.path('$'))\n$input.json(\"$\")\n#if($inputRoot.toString().contains(\"error\"))\n#set($context.responseOverride.status = 400)\n#end"
              }
            }
          },
          "requestParameters" : {
            "integration.request.path.petId" : "method.request.path.petId"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "Pet" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "integer"
          },
          "type" : {
            "type" : "string"
          },
          "price" : {
            "type" : "number"
          }
        }
      }
    }
  }
}
```

------

## 예제 2: 요청 헤더 재정의 및 새 헤더 만들기
<a name="apigateway-override-request-response-examples-2"></a>

다음 예제에서는 [예제 API](api-gateway-create-api-from-example.md)를 사용하여 요청 헤더를 재정의하고 새 헤더를 만듭니다.

------
#### [ AWS Management Console ]

**새 헤더를 만들어 메서드의 요청 헤더 재정의**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)에서 API Gateway 콘솔에 로그인합니다.

1. 이전 자습서에서 만든 예제 API를 선택합니다. API의 이름은 **PetStore**여야 합니다.

1. **리소스** 트리에서, `/pet` 아래의 `GET` 메서드를 선택합니다.

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

1. **HTTP 요청 헤더**를 선택한 다음, **헤더 추가**를 선택합니다.

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

1. **헤더 추가**를 선택한 다음 **header2**라는 두 번째 헤더를 생성합니다.

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

   이제 매핑 템플릿을 사용하여 이러한 헤더를 하나의 헤더 값으로 결합합니다.

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

1. **요청 본문 패스스루**에서 **정의된 템플릿이 없는 경우(권장)**를 선택합니다.

1. **매핑 템플릿**을 선택한 후 다음을 수행합니다.

   1. **매핑 템플릿 추가(Add mapping template)**를 선택합니다.

   1. **콘텐츠 유형**에 **application/json**을 입력합니다.

   1. **템플릿 본문**에 다음을 입력합니다.

      ```
      #set($header1Override = "pets")
      #set($header3Value = "$input.params('header1')$input.params('header2')")
      $input.json("$")
      #set($context.requestOverride.header.header3 = $header3Value)
      #set($context.requestOverride.header.header1 = $header1Override)
      #set($context.requestOverride.header.multivalueheader=[$header1Override, $header3Value])
      ```

      이 매핑 템플릿은 `pets` 문자열로 `header1`을 재정의하고 `header1` 및 `header2`를 결합하는 `$header3Value`라는 다중 값 헤더를 만듭니다.

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

1. **테스트** 탭을 선택합니다.

1. **헤더**에서 다음 코드를 복사합니다.

   ```
   header1:header1Val
   header2:header2Val
   ```

1. **테스트**를 선택합니다.

   **로그**에 다음 텍스트가 포함된 항목이 보입니다.

   ```
   Endpoint request headers: {header3=header1Valheader2Val, 
   header2=header2Val, header1=pets, x-amzn-apigateway-api-id=api-id,
   Accept=application/json, multivalueheader=pets,header1Valheader2Val}
   ```

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

 이 예제에서는 [본문](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) 속성을 사용하여 OpenAPI 정의 파일을 API Gateway로 가져옵니다.

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body: 
        openapi: 3.0.1
        info:
          title: PetStore Example 2
          description: Example pet store API.
          version: "2025-01-14T00:36:18Z"
        paths:
          /pets:
            get:
              parameters:
                - name: header2
                  in: header
                  schema:
                    type: string
                - name: page
                  in: query
                  schema:
                    type: string
                - name: type
                  in: query
                  schema:
                    type: string
                - name: header1
                  in: header
                  schema:
                    type: string
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets
                responses:
                  default:
                    statusCode: "200"
                requestParameters:
                  integration.request.header.header1: method.request.header.header1
                  integration.request.header.header2: method.request.header.header2
                  integration.request.querystring.page: method.request.querystring.page
                  integration.request.querystring.type: method.request.querystring.type
                requestTemplates:
                  application/json: |-
                    #set($header1Override = "pets")
                    #set($header3Value = "$input.params('header1')$input.params('header2')")
                    $input.json("$")
                    #set($context.requestOverride.header.header3 = $header3Value)
                    #set($context.requestOverride.header.header1 = $header1Override)
                    #set($context.requestOverride.header.multivalueheader=[$header1Override, $header3Value])
                passthroughBehavior: when_no_match
                type: http
        components:
          schemas:
            Pet:
              type: object
              properties:
                id:
                  type: integer
                type:
                  type: string
                price:
                  type: number
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  ApiGatewayDeployment20250219:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  Stage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
       DeploymentId: !Ref ApiGatewayDeployment20250219
       RestApiId: !Ref Api
       StageName: prod
```

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

 다음 OpenAPI 정의는 `GET pets` 리소스를 만들고 요청 헤더를 재정의하고 새 헤더를 만듭니다.

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "PetStore Example 2",
    "description" : "Example pet store API.",
    "version" : "2025-01-14T00:36:18Z"
  },
  "paths" : {
    "/pets" : {
      "get" : {
        "parameters" : [ {
          "name" : "header2",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "page",
          "in" : "query",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "type",
          "in" : "query",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "header1",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.header1" : "method.request.header.header1",
            "integration.request.header.header2" : "method.request.header.header2",
            "integration.request.querystring.page" : "method.request.querystring.page",
            "integration.request.querystring.type" : "method.request.querystring.type"
          },
          "requestTemplates" : {
            "application/json" : "#set($header1Override = \"pets\")\n#set($header3Value = \"$input.params('header1')$input.params('header2')\")\n$input.json(\"$\")\n#set($context.requestOverride.header.header3 = $header3Value)\n#set($context.requestOverride.header.header1 = $header1Override)\n#set($context.requestOverride.header.multivalueheader=[$header1Override, $header3Value])"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  }
}
```

------

매핑 템플릿 재정의를 사용하려면 다음 `$context` 변수 중 하나 이상을 추가합니다. `$context` 변수 목록은 [데이터 변환용 컨텍스트 변수](api-gateway-mapping-template-reference.md#context-variable-reference) 섹션을 참조하시기 바랍니다.