

# 为 API Gateway 中的 REST API 设置阶段变量
<a name="how-to-set-stage-variables-aws-console"></a>

此部分介绍如何使用 Amazon API Gateway 控制台为示例 API 的两个部署阶段设置阶段变量。要了解如何在 API Gateway 中使用阶段变量，建议您按照此部分中的所有过程进行操作。

## 先决条件
<a name="how-to-set-stage-variables-aws-console-prerequisites"></a>

在您开始之前，确保您满足以下先决条件：
+ API Gateway 中必须有可用的 API。按照中的说明进行操作[开发 API Gateway 中的 REST API](rest-api-develop.md)
+ 您必须至少部署过一次 API。按照中的说明进行操作[在 API Gateway 中部署 REST API。](how-to-deploy-api.md)
+ 您必须为已部署的 API 创建了第一个阶段。按照中的说明进行操作[创建新阶段](set-up-stages.md#how-to-create-stage-console)

  

## 使用阶段变量通过 API 调用 HTTP 端点
<a name="how-to-set-stage-variables-aws-console-http-endpoint"></a>

此过程介绍如何为 HTTP 端点创建阶段变量以及如何为 API 创建两个阶段。此外，您可以创建在此部分的以下过程中使用的阶段变量 `url`、`stageName` 和 `function`。

**使用阶段变量通过 API 调用 HTTP 端点**

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

1. 创建 API，然后在 API 的根资源上创建 `GET` 方法。将集成类型设置为 **HTTP**，并将**端点 URL** 设置为 **http://\$1\$1stageVariables.url\$1**。

1. 将 API 部署到名为 **beta** 的新阶段。

1. 在主导航窗格中，选择**阶段**，然后选择 **beta** 阶段。

1. 在**阶段变量**选项卡上，选择**编辑**。

1. 选择**添加阶段变量**。

1. 对于**名称**，请输入 **url**。对于**值**，输入 **httpbin.org/get**。

1. 选择**添加阶段变量**，然后执行以下操作：

   对于**名称**，请输入 **stageName**。对于**值**，输入 **beta**。

1. 选择**添加阶段变量**，然后执行以下操作：

   对于**名称**，请输入 **function**。对于**值**，输入 **HelloWorld**。

1. 选择**保存**。

1.  现在创建第二个阶段。从**阶段**导航窗格中，选择**创建阶段**。对于**阶段名称**，输入 **prod**。从**部署**中选择一个新近部署，然后选择**创建阶段**。

1.  与 **beta** 阶段一样，将相同的三个阶段变量（**url**、**stageName** 和 **function**）分别设置为不同的值（**petstore-demo-endpoint.execute-api.com/petstore/pets**、**prod** 和 **HelloEveryone**）。

1. 在**阶段**导航窗格中，选择 **beta** 阶段。在**阶段详细信息**下，选择复制图标以复制 API 的调用 URL，然后在 Web 浏览器中输入 API 的调用 URL。这将启动 API 根资源上的 **beta** 阶段 `GET` 请求。
**注意**  
**Invoke URL** 链接指向 API 在其 **beta** 阶段的根资源。在 Web 浏览器中输入 URL 会对根资源调用 **beta** 阶段 `GET` 方法。如果方法是在子资源而非根资源本身上定义的，则在 Web 浏览器中输入 URL 将返回 `{"message":"Missing Authentication Token"}` 错误响应。在这种情况下，您必须将特定子资源的名称附加到**调用 URL** 链接。

1. **beta** 阶段 `GET` 请求的响应如下所示。您还可以使用浏览器导航到 **http://httpbin.org/get**，以验证结果。此值已分配到 **beta** 阶段中的 `url` 变量。这两个响应完全相同。

1. 在**阶段**导航窗格中，选择 **prod** 阶段。在**阶段详细信息**下，选择复制图标以复制 API 的调用 URL，然后在 Web 浏览器中输入 API 的调用 URL。这将启动 API 根资源上的 **prod** 阶段 `GET` 请求。

1. **prod** 阶段 `GET` 请求的响应如下所示。您可以使用浏览器导航到 **http://petstore-demo-endpoint.execute-api.com/petstore/pets**，以验证结果。此值已分配到 **prod** 阶段中的 `url` 变量。这两个响应完全相同。

## 将特定于阶段的元数据传入 HTTP 后端
<a name="how-to-set-stage-variables-aws-console-stage-metadata"></a>

此过程介绍如何在查询参数表达式中使用阶段变量值将特定于阶段的元数据传递到 HTTP 后端。我们将使用上一个过程中声明的 `stageName` 阶段变量。

**将特定于阶段的元数据传入 HTTP 后端**

1. 在**资源**导航窗格中，选择 **GET** 方法。

   要向方法的 URL 添加查询字符串参数，请选择**方法请求**选项卡，然后在**方法请求设置**部分中选择**编辑**。

1. 选择 **URL 查询字符串参数**并执行以下操作：

   1. 选择**添加查询字符串**。

   1. 在**名称**中，输入 **stageName**。

   1. 保持**必填**和**缓存**为已关闭状态。

1. 选择**保存**。

1. 选择**集成请求**选项卡，然后在**集成请求设置**部分中，选择**编辑**。

1. 对于**端点 URL**，将 **?stageName=\$1\$1stageVariables.stageName\$1** 附加到先前定义的 URL 值，因此整个**端点 URL** 为 **http://\$1\$1stageVariables.url\$1?stageName=\$1\$1stageVariables.stageName\$1**。

1. 选择**部署 API**，然后选择 **beta** 阶段。

1. 在主导航窗格中，选择**阶段**。在**阶段**导航窗格中，选择 **beta** 阶段。在**阶段详细信息**下，选择复制图标以复制 API 的调用 URL，然后在 Web 浏览器中输入 API 的调用 URL。
**注意**  
 我们之所以在这里使用测试阶段，是因为 HTTP 端点（由 `url` 变量“http://httpbin.org/get”指定）接受查询参数表达式，并在响应中将其作为 `args` 对象返回。

1. 您将收到以下响应。注意，分配给 `beta` 阶段变量的 `stageName` 作为 `stageName` 参数传递到后端。

      
![\[使用 url 阶段变量通过 HTTP 端点从 API 的 GET 方法获取响应。\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/stageVariables-new-console-invoke-beta-stage-with-url-and-stageName-response.png)

## 使用阶段变量通过 API 调用 Lambda 函数
<a name="how-to-set-stage-variables-aws-console-lambda-function"></a>

此过程介绍了如何使用阶段变量调用 Lambda 函数作为 API 后端。您使用已在[使用阶段变量通过 API 调用 HTTP 端点](#how-to-set-stage-variables-aws-console-http-endpoint)中声明的 `function` 阶段变量。

 在将 Lambda 函数设置为阶段变量的值时，请使用函数的本地名称，可能包括其别名或版本规范，例如 **HelloWorld**、**HelloWorld:1** 或 **HelloWorld:alpha**。请勿使用该函数的 ARN（例如 **arn:aws:lambda:us-east-1:123456789012:function:HelloWorld**）。API Gateway 控制台将 Lambda 函数的阶段变量值假定为非限定的函数名称，并且会将给定的阶段变量扩展到 ARN 中。

**使用阶段变量通过 API 调用 Lambda 函数**

1. 使用默认 Node.js 运行时系统创建名为 **HelloWorld** 的 Lambda 函数。代码必须包含以下内容：

   ```
   export const handler = function(event, context, callback) {
       if (event.stageName)
           callback(null, 'Hello, World! I\'m calling from the ' + event.stageName + ' stage.');
       else
           callback(null, 'Hello, World! I\'m not sure where I\'m calling from...');
   };
   ```

   有关如何创建 Lambda 函数的更多信息，请参阅 [REST API 控制台入门](getting-started-rest-new-console.md#getting-started-rest-new-console-create-function)。

1. 在**资源**窗格中，选择**创建资源**，然后执行以下操作：

   1. 对于**资源路径**，选择 **/**。

   1. 对于**资源名称**，输入 **lambdav1**。

   1. 选择**创建资源**。

1. 选择 **/lambdav1** 资源，然后选择**创建方法**。

   然后执行以下操作：

   1. 对于**方法类型**，选择 **GET**。

   1. 对于**集成类型**，选择 **Lambda 函数**。

   1. 保持 **Lambda 代理集成**处于关闭状态。

   1. 对于 **Lambda 函数**，输入 `${stageVariables.function}`。  
![\[按照 function 阶段变量指定的方式，创建与 Lambda 函数集成的 GET 方法。\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/stageVariables-new-console-create-lambda-get-method.png)
**提示**  
当提示使用**添加权限命令**时，复制 [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) 命令。对将分配给 `function` 阶段变量的每个 Lambda 函数运行此命令。例如，如果 `$stageVariables.function` 值为 `HelloWorld`，则运行以下 AWS CLI 命令：  

      ```
      aws lambda add-permission --function-name arn:aws:lambda:us-east-1:account-id:function:HelloWorld --source-arn arn:aws:execute-api:us-east-1:account-id:api-id/*/GET/lambdav1 --principal apigateway.amazonaws.com --statement-id statement-id-guid --action lambda:InvokeFunction
      ```
 否则会导致在调用该方法时出现 `500 Internal Server Error` 响应。将 `${stageVariables.function}` 替换为已分配给阶段变量的 Lambda 函数名称。  
   

![\[AWS CLI 命令，以便添加针对要由您创建的方法调用的 Lambda 函数的权限。\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/stageVariables-new-console-add-permission-to-lambda-function.png)


   1. 选择**创建方法**。

1. 将 API 部署到 **prod** 和 **beta** 阶段。

1. 在主导航窗格中，选择**阶段**。在**阶段**导航窗格中，选择 **beta** 阶段。在**阶段详细信息**下，选择复制图标以复制 API 的调用 URL，然后在 Web 浏览器中输入 API 的调用 URL。在按 Enter 之前，将 **/lambdav1** 附加到 URL。

   您将收到以下响应。

   ```
   "Hello, World! I'm not sure where I'm calling from..."
   ```

## 通过阶段变量将特定于阶段的元数据传递到 Lambda 函数中
<a name="pass-version-info-to-lambda-backend-with-stage-variable"></a>

此过程介绍了如何使用阶段变量将特定于阶段的配置元数据传递到 Lambda 函数中。您创建 `POST` 方法和输入映射模板，以使用先前声明的 `stageName` 阶段变量生成负载。

**通过阶段变量将特定于阶段的元数据传递到 Lambda 函数中**

1. 选择 **/lambdav1** 资源，然后选择**创建方法**。

   然后执行以下操作：

   1. 对于**方法类型**，选择 **POST**。

   1. 对于**集成类型**，选择 **Lambda 函数**。

   1. 保持 **Lambda 代理集成**处于关闭状态。

   1. 对于 **Lambda 函数**，输入 `${stageVariables.function}`。

   1. 当提示使用**添加权限命令**时，复制 [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) 命令。对将分配给 `function` 阶段变量的每个 Lambda 函数运行此命令。

   1. 选择**创建方法**。

1. 选择**集成请求**选项卡，然后在**集成请求设置**部分中，选择**编辑**。

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

1. 对于**内容类型**，输入 **application/json**。

1. 对于**模板正文**，输入以下模板：

   ```
   #set($inputRoot = $input.path('$'))
   {
       "stageName" : "$stageVariables.stageName"
   }
   ```
**注意**  
 在映射模板中，阶段变量必须在引号中引用（如 `"$stageVariables.stageName"` 或 `"${stageVariables.stageName}"` 中所示）。在其他位置，必须不带引号引用（如 `${stageVariables.function}` 中所示）。

1. 选择**保存**。

1. 将 API 部署到 **beta** 和 **prod** 阶段。

1. 要使用 REST API 客户端传递特定于阶段的元数据，请执行以下操作：

   1. 在**阶段**导航窗格中，选择 **beta** 阶段。在**阶段详细信息**下，选择复制图标以复制 API 的调用 URL，然后在 REST API 客户端的输入字段中输入 API 的调用 URL。在提交请求之前附加 **/lambdav1**。

      您将收到以下响应。

      ```
      "Hello, World! I'm calling from the beta stage."
      ```

   1. 在**阶段**导航窗格中，选择 **prod**。在**阶段详细信息**下，选择复制图标以复制 API 的调用 URL，然后在 REST API 客户端的输入字段中输入 API 的调用 URL。在提交请求之前附加 **/lambdav1**。

      您将收到以下响应。

      ```
      "Hello, World! I'm calling from the prod stage."
      ```

1. 要使用**测试**特征传递特定于阶段的元数据，请执行以下操作：

   1. 在**资源**导航窗格中，选择**测试**选项卡。您可能需要选择右箭头按钮以显示该选项卡。

   1. 对于 **function**，请输入 **HelloWorld**。

   1. 对于 **stageName**，请输入 **beta**。

   1. 选择**测试**。您无需将正文添加到您的 `POST` 请求。

      您将收到以下响应。

      ```
      "Hello, World! I'm calling from the beta stage."
      ```

   1. 您可以重复前面的步骤来测试 **Prod** 阶段。对于 **stageName**，请输入 **Prod**。

      您将收到以下响应。

      ```
      "Hello, World! I'm calling from the prod stage."
      ```