

# 针对 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 管理控制台 ]

**基于集成响应正文覆盖状态代码**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 选择**创建 API**。

1. 对于 **REST API**，选择**构建**。

1. 对于 **API 详细信息**，选择**示例 API**。

1. 选择**创建 API**。

   API Gateway 创建一个示例宠物商店 API。要检索有关宠物的信息，您使用 API 方法请求 `GET /pets/{petId}`，其中 `{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. 选择**添加映射模板**。

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. 在结果中，**响应正文**表示超出范围错误：

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

   不过，**日志**下的最后一行现在的结尾为：`Method completed with status: 400`。

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

 在此示例中，您使用 [body](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 管理控制台 ]

**通过创建新标头覆盖方法的请求标头**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 选择您在先前教程中创建的示例 API。API 的名称应为 **PetStore**。

1. 在**资源**树中，选择 `/pet` 下的 `GET` 方法。

1. 在**方法请求**选项卡上，对于**方法请求设置**，选择**编辑**。

1. 选择 **HTTP 请求标头**，然后选择**添加标头**。

1. 对于**名称**，请输入 **header1**。

1. 选择**添加标头**，然后创建第二个标头，名为 **header2**。

1. 选择**保存**。

   现在，您可以使用映射模板将这些标头合并为一个标头值。

1. 在**集成请求**选项卡上，对于**集成请求设置**，选择**编辑**。

1. 对于**请求正文传递**，选择**当未定义模板时（推荐）**。

1. 选择**映射模板**，然后执行以下操作：

   1. 选择**添加映射模板**。

   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`，并创建一个名为 `$header3Value` 的多值标头，该标头将 `header1` 和 `header2` 组合在一起。

1. 选择**保存**。

1. 选择**测试**选项卡。

1. 在**标头**下，复制以下代码：

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

1. 选择 **Test (测试)**。

   在**日志**中，您应看到一个包含此文本的条目：

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

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

 在此示例中，您使用 [body](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)。