

# 选择 AWS Lambda 集成教程
<a name="getting-started-with-lambda-integration"></a>

 要使用 Lambda 集成构建 API，您可以使用 Lambda 代理集成或 Lambda 非代理集成。

使用 Lambda 代理集成，Lambda 函数的输入可以表示为请求标头、路径变量、查询字符串参数、正文和 API 配置数据的任意组合。您只需选择 Lambda 函数。API Gateway 将为您配置集成请求和集成响应。设置完成后，API 方法会发生变化，而不会修改现有设置。之所以能做到这一点，是因为后端 Lambda 函数会解析传入的请求数据，并响应客户端。

在 Lambda 非代理集成中，您必须确保将 Lambda 函数的输入作为集成请求负载进行提供。您必须将客户端作为请求参数提供的任何输入数据映射到正确的集成请求正文。您可能还需要将客户端提供的请求正文转换为 Lambda 函数可识别的格式。

在 Lambda 代理或 Lambda 非代理集成中，您可以在一个账户中创建 API，而在另一个账户中使用 Lambda 函数。

**Topics**
+ [教程：利用 Lambda 代理集成创建 REST API](api-gateway-create-api-as-simple-proxy-for-lambda.md)
+ [教程：利用 Lambda 非代理集成创建 REST API](getting-started-lambda-non-proxy-integration.md)
+ [教程：利用跨账户 Lambda 代理集成创建 REST API](apigateway-cross-account-lambda-integrations.md)

# 教程：利用 Lambda 代理集成创建 REST API
<a name="api-gateway-create-api-as-simple-proxy-for-lambda"></a>

[Lambda 代理集成](set-up-lambda-proxy-integrations.md) 是一种轻量型、灵活的 API Gateway API 集成类型，可让您能够使用 Lambda 函数集成 API 方法（或整个 API）。Lambda 函数可以用 [Lambda 支持的任何语言](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)编写。由于这是代理集成，因此您可以随时更改 Lambda 函数实现，而无需重新部署您的 API。

在本教程中，您将执行以下操作：
+ 创建“Hello, World\$1” 要作为 API 的后端的 Lambda 函数。
+ 创建并测试“Hello, World\$1” API 与 Lambda 代理集成。

**Topics**
+ [创建“Hello, World\$1” Lambda 函数](#api-gateway-proxy-integration-create-lambda-backend)
+ [创建“Hello, World\$1” API](#api-gateway-create-api-as-simple-proxy-for-lambda-build)
+ [部署并测试 API](#api-gateway-create-api-as-simple-proxy-for-lambda-test)

## 创建“Hello, World\$1” Lambda 函数
<a name="api-gateway-proxy-integration-create-lambda-backend"></a>

**创建“Hello, World\$1” Lambda 控制台中的 Lambda 函数**

1. 通过以下网址登录 Lambda 控制台：[https://console.aws.amazon.com/lambda](https://console.aws.amazon.com/lambda)。

1. 在 AWS 导航栏上，选择 [AWS 区域](https://docs.aws.amazon.com/general/latest/gr/apigateway.html)。
**注意**  
请注意您创建 Lambda 函数时所在的区域。在创建 API 时，会需要它。

1. 在导航窗格中，选择**函数**。

1. 选择**创建函数**。

1. 选择**从头开始创作**。

1. 在**基本信息**中，执行以下操作：

   1. 在**函数名称**中，输入 **GetStartedLambdaProxyIntegration**。

   1. 在**运行时**中，选择受支持的最新 **Node.js** 或 **Python** 运行时。

   1. 对于**架构**，请保留默认设置。

   1. 在**权限**下，展开**更改默认执行角色**。在**执行角色**下拉列表中，选择**从 AWS 策略模板创建新角色**。

   1. 在**角色名称**中，输入 **GetStartedLambdaBasicExecutionRole**。

   1. 将**策略模板**字段留空。

   1. 选择**创建函数**。

1. 在内联代码编辑器的**函数代码**下，复制/粘贴以下代码：

------
#### [ Node.js ]

   ```
   export const handler = async(event, context) => {
       console.log('Received event:', JSON.stringify(event, null, 2));
       var res ={
           "statusCode": 200,
           "headers": {
               "Content-Type": "*/*"
           }
       };
       var greeter = 'World';
       if (event.greeter && event.greeter!=="") {
           greeter =  event.greeter;
       } else if (event.body && event.body !== "") {
           var body = JSON.parse(event.body);
           if (body.greeter && body.greeter !== "") {
               greeter = body.greeter;
           }
       } else if (event.queryStringParameters && event.queryStringParameters.greeter && event.queryStringParameters.greeter !== "") {
           greeter = event.queryStringParameters.greeter;
       } else if (event.multiValueHeaders && event.multiValueHeaders.greeter && event.multiValueHeaders.greeter != "") {
           greeter = event.multiValueHeaders.greeter.join(" and ");
       } else if (event.headers && event.headers.greeter && event.headers.greeter != "") {
           greeter = event.headers.greeter;
       } 
       res.body = "Hello, " + greeter + "!";
       return res
   };
   ```

------
#### [ Python ]

   ```
   import json
   
   
   def lambda_handler(event, context):
       print(event)
   
       greeter = 'World'
   
       try:
           if (event['queryStringParameters']) and (event['queryStringParameters']['greeter']) and (
                   event['queryStringParameters']['greeter'] is not None):
               greeter = event['queryStringParameters']['greeter']
       except KeyError:
           print('No greeter')
   
       try:
           if (event['multiValueHeaders']) and (event['multiValueHeaders']['greeter']) and (
                   event['multiValueHeaders']['greeter'] is not None):
               greeter = " and ".join(event['multiValueHeaders']['greeter'])
       except KeyError:
           print('No greeter')
   
       try:
           if (event['headers']) and (event['headers']['greeter']) and (
                   event['headers']['greeter'] is not None):
               greeter = event['headers']['greeter']
       except KeyError:
           print('No greeter')
   
       if (event['body']) and (event['body'] is not None):
           body = json.loads(event['body'])
           try:
               if (body['greeter']) and (body['greeter'] is not None):
                   greeter = body['greeter']
           except KeyError:
               print('No greeter')
   
       res = {
           "statusCode": 200,
           "headers": {
               "Content-Type": "*/*"
           },
           "body": "Hello, " + greeter + "!"
       }
   
       return res
   ```

------

1. 选择**部署**。

## 创建“Hello, World\$1” API
<a name="api-gateway-create-api-as-simple-proxy-for-lambda-build"></a>

现在为您的“Hello, World\$1”创建 API。使用 API Gateway 控制台的 Lambda 函数。

**创建“Hello, World\$1” API**

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

1. 如果您是第一次使用 API Gateway，您会看到一个介绍服务特征的页面。在 **REST API** 下，选择**生成**。当**创建示例 API** 弹出框出现时，选择**确定**。

   如果这不是您首次使用 API Gateway，请选择**创建 API**。在 **REST API** 下，选择**生成**。

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

1. （可选）对于**描述**，输入描述。

1. 将 **API 端点类型**设置保留为**区域**。

1. 为 **IP 地址类型**选择 **IPv4**。

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

创建 API 后，您将创建一个资源。通常情况下，根据应用程序逻辑将 API 资源组织成资源树形式。在本示例中，您将创建一个 **/helloworld** 资源。

**创建资源**

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

1. 将**代理资源**保持为关闭状态。

1. 将**资源路径**保持为 `/`。

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

1. 将 **CORS（跨源资源共享）**保持为关闭状态。

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

 在代理集成中，整个请求将通过表示任何 HTTP 方法的“捕获全部”`ANY` 方法按原样发送到后端 Lambda 函数。实际的 HTTP 方法由客户端在运行时指定。`ANY` 方法可让您对所有支持的 HTTP 方法使用单个 API 方法设置：`DELETE`、`GET`、`HEAD`、`OPTIONS`、`PATCH`、`POST` 和 `PUT`。

**创建 `ANY` 方法**

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

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

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

1. 打开 **Lambda 代理集成**。

1. 对于 **Lambda 函数**，选择您创建 Lambda 函数的 AWS 区域，然后输入函数名称。

1. 要使用默认超时值 29 秒，请保持**默认超时**处于开启状态。要设置自定义超时，请选择**默认超时**，然后输入一个介于 `50` 到 `29000` 毫秒之间的超时值。

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

## 部署并测试 API
<a name="api-gateway-create-api-as-simple-proxy-for-lambda-test"></a>

**部署 API**

1. 选择**部署 API**。

1. 对于**阶段**，选择**新建阶段**。

1. 对于**阶段名称**，输入 **test**。

1. （可选）对于**描述**，输入描述。

1. 选择**部署**。

1. 在**阶段详细信息**下，选择复制图标以复制您 API 的调用 URL。

### 使用浏览器和 cURL 来通过 Lambda 代理集成测试 API
<a name="api-gateway-create-api-as-simple-proxy-for-lambda-test-curl"></a>

您可以使用浏览器或 [cURL](https://curl.se/) 来测试您的 API。

要仅使用查询字符串参数测试 `GET` 请求，您可以在浏览器地址栏中输入 API 的 `helloworld` 资源的 URL。

要创建 API 的 `helloworld` 资源的 URL，请将资源 `helloworld` 和查询字符串参数 `?greeter=John` 附加到您的调用 URL。URL 应类似以下内容。

```
https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld?greeter=John
```

对于其他方法，您必须使用更高级的 REST API 测试实用程序，如 [POSTMAN](https://www.postman.com/) 或 [cURL](https://curl.se/)。本教程使用的是 cURL。以下 cURL 命令示例假定您的计算机上已安装 cURL。

**使用 cURL 测试已部署的 API：**

1. 打开终端窗口。

1. 复制以下 cURL 命令并粘贴到终端窗口中，将调用 URL 替换为在上一步中复制的调用 URL，并在该 URL 的末尾添加 **/helloworld**。
**注意**  
如果您在 Windows 上运行命令，请改用以下语法：  

   ```
   curl -v -X POST "https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld" -H "content-type: application/json" -d "{ \"greeter\": \"John\" }"
   ```

   1. 使用查询字符串参数 `?greeter=John` 调用 API：

      ```
      curl -X GET 'https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld?greeter=John'
      ```

   1. 使用标头参数 `greeter:John` 调用 API：

      ```
      curl -X GET https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld \
        -H 'content-type: application/json' \
        -H 'greeter: John'
      ```

   1. 使用正文 `{"greeter":"John"}` 调用 API：

      ```
      curl -X POST https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld \
        -H 'content-type: application/json' \
        -d '{ "greeter": "John" }'
      ```

   在所有情况下，输出为具有以下响应正文的 200 响应：

   ```
   Hello, John!
   ```

# 教程：利用 Lambda 非代理集成创建 REST API
<a name="getting-started-lambda-non-proxy-integration"></a>

在本演练中，我们使用 API Gateway 控制台构建一个 API，该 API 允许客户端通过 Lambda 非代理集成（又称为“自定义集成”）来调用 Lambda 函数。有关 AWS Lambda 和 Lambda 函数的更多信息，请参阅 [AWS Lambda 开发人员指南](https://docs.aws.amazon.com/lambda/latest/dg/)。

为了便于学习，我们选择了一个所需 API 设置最少的简单 Lambda 函数，逐步指导您完成使用 Lambda 自定义集成构建 API Gateway API 的步骤。必要时，我们会介绍一些逻辑。有关 Lambda 自定义集成的更详细示例，请参阅 [教程：通过两种 AWS 服务集成和一种 Lambda 非代理集成创建计算器 REST API](integrating-api-with-aws-services-lambda.md)。

在创建 API 之前，请通过在 AWS Lambda 中创建 Lambda 函数来设置 Lambda 后端，如下所述。

**Topics**
+ [为 Lambda 非代理集成创建 Lambda 函数](#getting-started-new-lambda)
+ [使用 Lambda 非代理集成创建 API](#getting-started-new-api)
+ [测试 API 方法的调用](#getting-started-new-get)
+ [部署 API](#getting-started-deploy-api)
+ [在部署阶段测试 API](#getting-started-test)
+ [清除](#getting-started-clean-up)

## 为 Lambda 非代理集成创建 Lambda 函数
<a name="getting-started-new-lambda"></a>

**注意**  
创建 Lambda 函数可能会导致您的AWS账户产生费用。

 在此步骤中，您将为 Lambda 自定义集成创建一个如“Hello, World\$1”的 Lambda 函数。在本演练中，该函数称为 `GetStartedLambdaIntegration`。

 该 `GetStartedLambdaIntegration` Lambda 函数的实现如下所示：

------
#### [ Node.js ]

```
'use strict';
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];            
var times = ['morning', 'afternoon', 'evening', 'night', 'day'];

export const handler = async(event) => {
  console.log(event);
  // Parse the input for the name, city, time and day property values
  let name = event.name === null || event.name === undefined || event.name === "" ? 'you' : event.name;
  let city = event.city === undefined ? 'World' : event.city;
  let time = times.indexOf(event.time)<0 ? 'day' : event.time;
  let day = days.indexOf(event.day)<0 ? null : event.day;

  // Generate a greeting
  let greeting = 'Good ' + time + ', ' + name + ' of ' + city + '. ';
  if (day) greeting += 'Happy ' + day + '!';
  
  // Log the greeting to CloudWatch
  console.log('Hello: ', greeting);
  
  // Return a greeting to the caller
  return {"greeting": greeting}
};
```

------
#### [ Python ]

```
import json

days = {
    'Sunday',
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday'}
times = {'morning', 'afternoon', 'evening', 'night', 'day'}


def lambda_handler(event, context):
    print(event)
    # parse the input for the name, city, time, and day property values
    name = event.get("name") or 'you'
    city = event.get("city") or 'World'
    try:
        if event['time'] in times:
            time = event['time']
        else:
            time = 'day'
    except KeyError:
        time = 'day'
    try:
        if event['day'] in days:
            day = event['day']
        else:
            day = ''
    except KeyError:
        day = ''
    # Generate a greeting
    greeting = 'Good ' + time + ', ' + name + ' of ' + \
        city + '.' + ['', ' Happy ' + day + '!'][day != '']
    # Log the greeting to CloudWatch
    print(greeting)

    # Return a greeting to the caller
    return {"greeting": greeting}
```

------

对于 Lambda 自定义集成，API Gateway 会将来自客户端的 Lambda 函数的输入作为集成请求正文来传递。Lambda 函数处理程序的 `event` 对象是输入。

我们的 Lambda 函数很简单。它会解析输入 `event` 对象的 `name`、`city`、`time` 和 `day` 属性。然后，它会以 `{"message":greeting}` 的 JSON 对象的形式向调用方返回问候语。该消息采用 `"Good [morning|afternoon|day], [name|you] in [city|World]. Happy day!"` 模式。假设 Lambda 函数的输入属于以下 JSON 对象：

```
{
  "city": "...",
  "time": "...",
  "day": "...",
  "name" : "..."
}
```

有关更多信息，请参阅 [AWS Lambda 开发人员指南](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)。

此外，该函数通过调用 `console.log(...)` 将其执行记录到 Amazon CloudWatch。这有助于在调试函数时跟踪调用。要允许 `GetStartedLambdaIntegration` 函数记录调用，请用用于 Lambda 函数的适当策略来设置 IAM 角色，以创建 CloudWatch 流并向流中添加日志条目。Lambda 控制台将指导您创建所需的 IAM 角色和策略。

如果您设置 API 时不使用 API Gateway 控制台（例如，当[从 OpenAPI 导入 API](https://github.com/aws-samples/api-gateway-secure-pet-store/blob/master/src/main/resources/swagger.yaml#L39) 时），您必须显式创建（如有必要）并设置调用角色和策略以便 API Gateway 调用 Lambda 函数。有关如何为 API Gateway API 设置 Lambda 调用和执行角色的更多信息，请参阅[使用 IAM 权限控制对 REST API 的访问](permissions.md)。

 与用于 Lambda 代理集成的 Lambda 函数 `GetStartedLambdaProxyIntegration` 相比，用于 Lambda 自定义集成的 `GetStartedLambdaIntegration` Lambda 函数仅从 API Gateway API 集成请求正文中获取输入。该函数可以返回任何 JSON 对象、字符串、数字、布尔值甚至是二进制 blob 形式的输出。相比而言，用于 Lambda 代理集成的 Lambda 函数可从任何请求数据获取输入，但必须返回特定 JSON 对象形式的输出。用于 Lambda 自定义集成的 `GetStartedLambdaIntegration` 函数可以使用 API 请求参数作为输入，前提是 API Gateway 在将客户端请求转发至后端之前，将所需的 API 请求参数映射至集成请求正文。要实现这一点，API 开发人员必须在创建 API 时创建一个映射模板并在 API 方法中对其进行配置。

现在，创建 `GetStartedLambdaIntegration` Lambda 函数。

**为 Lambda 自定义集成创建 `GetStartedLambdaIntegration` Lambda 函数**

1. 打开 AWS Lambda 控制台，地址：[https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/)。

1. 请执行下列操作之一：
   + 如果显示欢迎页面，请选择**立即开始使用**，然后选择**创建函数**。
   + 如果显示 **Lambda > 函数**列表页面，请选择**创建函数**。

1. 选择**从头开始创作**。

1. 在**从头开始创作**窗格中，执行以下操作：

   1. 在**名称**中，输入 **GetStartedLambdaIntegration** 作为 Lambda 函数名称。

   1. 在**运行时**中，选择受支持的最新 **Node.js** 或 **Python** 运行时。

   1. 对于**架构**，请保留默认设置。

   1. 在**权限**下，展开**更改默认执行角色**。在**执行角色**下拉列表中，选择**从 AWS 策略模板创建新角色**。

   1. 对于**角色名称**，输入您角色的名称（例如 **GetStartedLambdaIntegrationRole**）。

   1. 对于**策略模板**，选择**简单微服务权限**。

   1. 选择**创建函数**。

1. 在**配置函数**窗格中的**函数代码**下，执行以下操作：

   1. 复制本节开头部分列出的 Lambda 函数代码并将其粘贴到内联代码编辑器中。

   1. 对本部分中的所有其他字段保留默认选择。

   1. 选择**部署**。

1. 要测试新创建的函数，请选择**测试**选项卡。

   1. 对于**事件名称**，输入 **HelloWorldTest**。

   1. 对于**事件 JSON**，请将默认代码替换为以下代码。

      ```
      {
        "name": "Jonny",
        "city": "Seattle",
        "time": "morning",
        "day": "Wednesday"
      }
      ```

   1.  选择**测试**以调用该函数。将显示**执行结果: 成功**部分。展开**详细信息**，您会看到以下输出。

      ```
      {
          "greeting": "Good morning, Jonny of Seattle. Happy Wednesday!"
      }
      ```

      还会将输出写入 CloudWatch Logs 中。

 作为同步练习，您可以使用 IAM 控制台查看 IAM 角色 (`GetStartedLambdaIntegrationRole`)，此角色是在创建 Lambda 函数的过程中创建的。此 IAM 角色附加了两个内联策略。一个策略规定 Lambda 执行的最基本权限。它允许在创建 Lambda 函数的区域中为您账户的任何 CloudWatch 资源调用 CloudWatch `CreateLogGroup`。此策略还允许创建 CloudWatch 流和为 `GetStartedLambdaIntegration` Lambda 函数记录事件。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "logs:CreateLogGroup",
            "Resource": "arn:aws:logs:us-east-1:111111111111:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:us-east-1:111111111111:log-group:/aws/lambda/GetStartedLambdaIntegration:*"
            ]
        }
    ]
}
```

------

另一个策略文档适用于调用此示例中未使用的其他 AWS 服务。您可以暂时跳过此策略。

 与 IAM 角色关联的是可信实体 `lambda.amazonaws.com`。下面是信任关系：

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

 此信任关系与内联策略的组合，使得 Lambda 函数能够调用 `console.log()` 函数来将事件记录到 CloudWatch Logs。

## 使用 Lambda 非代理集成创建 API
<a name="getting-started-new-api"></a>

 创建并测试 Lambda 函数 (`GetStartedLambdaIntegration`) 后，您便已准备就绪，可以通过 API Gateway API 来公开该函数。为了便于说明，我们用通用 HTTP 方法公开 Lambda 函数。我们使用请求正文、URL 路径变量、查询字符串和标头来接收来自客户端的所需输入数据。我们为 API 启用 API Gateway 请求验证程序，以确保正确定义并指定所有必需的数据。我们为 API Gateway 配置映射模板，以根据后端 Lambda 函数的要求将客户端提供的请求数据转换为有效格式。

**使用 Lambda 非代理集成创建 API**

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

1. 如果您是第一次使用 API Gateway，您会看到一个介绍服务特征的页面。在 **REST API** 下，选择**生成**。当**创建示例 API** 弹出框出现时，选择**确定**。

   如果这不是您首次使用 API Gateway，请选择**创建 API**。在 **REST API** 下，选择**生成**。

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

1. （可选）对于**描述**，输入描述。

1. 将 **API 端点类型**设置保留为**区域**。

1. 为 **IP 地址类型**选择 **IPv4**。

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

创建 API 后，您将创建一个 **/\$1city\$1** 资源。这是带有从客户端获取输入的路径变量的资源示例。稍后，您将使用映射模板将此路径变量映射到 Lambda 函数输入。

**创建资源**

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

1. 将**代理资源**保持为关闭状态。

1. 将**资源路径**保持为 `/`。

1. 对于**资源名称**，输入 **\$1city\$1**。

1. 将 **CORS（跨源资源共享）**保持为关闭状态。

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

创建 **/\$1city\$1** 资源后，您将创建一个 `ANY` 方法。`ANY` HTTP 动词是客户端在运行时提交的有效 HTTP 方法的占位符。此示例显示，`ANY` 方法可用于 Lambda 自定义集成和 Lambda 代理集成。

**创建 `ANY` 方法**

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

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

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

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

1. 对于 **Lambda 函数**，选择您创建 Lambda 函数的 AWS 区域，然后输入函数名称。

1. 选择**方法请求设置**。

   现在，您可以为 URL 路径变量、查询字符串参数和标头开启请求验证程序，来确保定义了所有必需的数据。在本示例中，您将创建一个 `time` 查询字符串参数和一个 `day` 标头。

1. 对于**请求验证程序**，选择**验证查询字符串参数和标头**。

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

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

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

   1. 打开**必需**。

   1. 将**缓存**保持为关闭状态。

1. 选择 **HTTP 请求标头**并执行以下操作：

   1. 选择**添加标头**。

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

   1. 打开**必需**。

   1. 将**缓存**保持为关闭状态。

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

打开请求验证程序后，您可以根据后端 Lambda 函数的要求，通过添加正文映射模板来配置 `ANY` 方法的集成请求，以将传入的请求转换为 JSON 负载。

**配置集成请求**

1. 在**集成请求**选项卡的**集成请求设置**下，选择**编辑**。

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

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

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

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

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

   ```
   #set($inputRoot = $input.path('$'))
   {
     "city": "$input.params('city')",
     "time": "$input.params('time')",
     "day":  "$input.params('day')",
     "name": "$inputRoot.callerName"
   }
   ```

1. 选择 **Save**。

## 测试 API 方法的调用
<a name="getting-started-new-get"></a>

 API Gateway 控制台提供了测试工具，以供您在部署 API 之前测试 API 的调用。您使用控制台的测试特征通过提交以下请求来测试 API：

```
POST /Seattle?time=morning
day:Wednesday

{
    "callerName": "John"
}
```

 在此测试请求中，您可以将 `ANY` 设置为 `POST`、将 `{city}` 设置为 `Seattle`、将 `Wednesday` 分配为 `day` 标头值，将 `"John"` 分配为 `callerName` 值。

**测试 `ANY` 方法**

1. 选择**测试**选项卡。您可能需要选择右箭头按钮，以显示该选项卡。

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

1. 对于**路径**，在**城市**下输入 **Seattle**。

1. 对于**查询字符串**，输入 **time=morning**。

1. 对于**标头**，输入 **day:Wednesday**。

1. 对于**请求正文**，输入 **\$1 "callerName": "John" \$1**。

1. 选择**测试**。

验证返回的响应负载是否如下所示：

```
{
  "greeting": "Good morning, John of Seattle. Happy Wednesday!"
}
```

您还可以查看日志，以确定 API Gateway 如何处理请求和响应。

```
Execution log for request test-request
Thu Aug 31 01:07:25 UTC 2017 : Starting execution for request: test-invoke-request
Thu Aug 31 01:07:25 UTC 2017 : HTTP Method: POST, Resource Path: /Seattle
Thu Aug 31 01:07:25 UTC 2017 : Method request path: {city=Seattle}
Thu Aug 31 01:07:25 UTC 2017 : Method request query string: {time=morning}
Thu Aug 31 01:07:25 UTC 2017 : Method request headers: {day=Wednesday}
Thu Aug 31 01:07:25 UTC 2017 : Method request body before transformations: { "callerName": "John" }
Thu Aug 31 01:07:25 UTC 2017 : Request validation succeeded for content type application/json
Thu Aug 31 01:07:25 UTC 2017 : Endpoint request URI: https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:GetStartedLambdaIntegration/invocations
Thu Aug 31 01:07:25 UTC 2017 : Endpoint request headers: {x-amzn-lambda-integration-tag=test-request, Authorization=****************************************************************************************************************************************************************************************************************************************************************************************************************************************338c72, X-Amz-Date=20170831T010725Z, x-amzn-apigateway-api-id=beags1mnid, X-Amz-Source-Arn=arn:aws:execute-api:us-west-2:123456789012:beags1mnid/null/POST/{city}, Accept=application/json, User-Agent=AmazonAPIGateway_beags1mnid, X-Amz-Security-Token=FQoDYXdzELL//////////wEaDMHGzEdEOT/VvGhabiK3AzgKrJw+3zLqJZG4PhOq12K6W21+QotY2rrZyOzqhLoiuRg3CAYNQ2eqgL5D54+63ey9bIdtwHGoyBdq8ecWxJK/YUnT2Rau0L9HCG5p7FC05h3IvwlFfvcidQNXeYvsKJTLXI05/yEnY3ttIAnpNYLOezD9Es8rBfyruHfJfOqextKlsC8DymCcqlGkig8qLKcZ0hWJWVwiPJiFgL7laabXs++ZhCa4hdZo4iqlG729DE4gaV1mJVdoAagIUwLMo+y4NxFDu0r7I0/EO5nYcCrppGVVBYiGk7H4T6sXuhTkbNNqVmXtV3ch5bOlh7 [TRUNCATED]
Thu Aug 31 01:07:25 UTC 2017 : Endpoint request body after transformations: {
  "city": "Seattle",
  "time": "morning",
  "day": "Wednesday",
  "name" : "John"
}
Thu Aug 31 01:07:25 UTC 2017 : Sending request to https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:GetStartedLambdaIntegration/invocations
Thu Aug 31 01:07:25 UTC 2017 : Received response. Integration latency: 328 ms
Thu Aug 31 01:07:25 UTC 2017 : Endpoint response body before transformations: {"greeting":"Good morning, John of Seattle. Happy Wednesday!"}
Thu Aug 31 01:07:25 UTC 2017 : Endpoint response headers: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=c0475a28-8de8-11e7-8d3f-4183da788f0f, Connection=keep-alive, Content-Length=62, Date=Thu, 31 Aug 2017 01:07:25 GMT, X-Amzn-Trace-Id=root=1-59a7614d-373151b01b0713127e646635;sampled=0, Content-Type=application/json}
Thu Aug 31 01:07:25 UTC 2017 : Method response body after transformations: {"greeting":"Good morning, John of Seattle. Happy Wednesday!"}
Thu Aug 31 01:07:25 UTC 2017 : Method response headers: {X-Amzn-Trace-Id=sampled=0;root=1-59a7614d-373151b01b0713127e646635, Content-Type=application/json}
Thu Aug 31 01:07:25 UTC 2017 : Successfully completed execution
Thu Aug 31 01:07:25 UTC 2017 : Method completed with status: 200
```

日志在映射之前显示传入请求并在映射之后显示集成请求。当测试失败时，日志对于评估原始输入是否正确或映射模板工作是否正常很有用。

## 部署 API
<a name="getting-started-deploy-api"></a>

 测试调用是一种模拟，会受到一些限制。例如，它会绕过 API 中应用的任何授权机制。要实时测试 API 执行，您必须先部署 API。要部署 API，您需创建一个阶段，以创建当时的 API 快照。阶段名称还定义在 API 的默认主机名后面的基本路径。API 的根资源附加在阶段名称之后。当您修改 API 时，必须将其重新部署到新阶段或现有阶段，然后更改才会生效。

**将 API 部署到某个阶段**

1. 选择**部署 API**。

1. 对于**阶段**，选择**新建阶段**。

1. 对于**阶段名称**，输入 **test**。
**注意**  
输入必须是 UTF-8 编码（即未本地化）的文本。

1. （可选）对于**描述**，输入描述。

1. 选择**部署**。

在**阶段详细信息**下，选择复制图标以复制您 API 的调用 URL。API 的基本 URL 的一般模式是 `https://api-id.region.amazonaws.com/stageName`。例如，在 `beags1mnid` 区域中创建并部署到 `us-west-2` 阶段的 API (`test`) 的基本 URL 是 `https://beags1mnid.execute-api.us-west-2.amazonaws.com/test`。

## 在部署阶段测试 API
<a name="getting-started-test"></a>

可通过若干种方法来测试已部署的 API。对于仅使用 URL 路径变量或查询字符串参数的 GET 请求，您可以在浏览器中输入 API 资源 URL。对于其他方法，您必须使用更高级的 REST API 测试实用程序，如 [POSTMAN](https://www.postman.com/) 或 [cURL](https://curl.se/)。

**使用 cURL 测试 API**

1. 在连接到 Internet 的本地计算机上打开终端窗口。

1. 测试 `POST /Seattle?time=evening`：

   复制以下 cURL 命令并将其粘贴到终端窗口中。

   ```
   curl -v -X POST \
     'https://beags1mnid.execute-api.us-west-2.amazonaws.com/test/Seattle?time=evening' \
     -H 'content-type: application/json' \
     -H 'day: Thursday' \
     -H 'x-amz-docs-region: us-west-2' \
     -d '{
   	"callerName": "John"
   }'
   ```

   您应获得一个包含以下负载的成功响应：

   ```
   {"greeting":"Good evening, John of Seattle. Happy Thursday!"}
   ```

   如果您在此方法请求中将 `POST` 更改为 `PUT`，则会获得相同的响应。

## 清除
<a name="getting-started-clean-up"></a>

如果您不再需要您为本演练创建的 Lambda 函数，现在可以将其删除。您也可以删除附带的 IAM 资源。

**警告**  
如果您计划完成本系列中的其他演练，请不要删除 Lambda 执行角色或 Lambda 调用角色。如果您删除您的 API 所依赖的某个 Lambda 函数，这些 API 将不再有效。Lambda 函数删除操作无法撤消。如果您要再次使用 Lambda 函数，必须重新创建该函数。  
如果您删除 Lambda 函数所依赖的 IAM 资源，Lambda 函数将不再有效，依赖于此函数的 API 也不再有效。IAM 资源删除操作无法撤消。如果您要再次使用 IAM 资源，必须重新创建该资源。

**删除 Lambda 函数**

1. 登录到 AWS 管理控制台，然后通过以下网址打开 AWS Lambda 控制台：[https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/)。

1. 从函数列表中选择 **GetStartedLambdaIntegration**，再选择**操作**，然后选择**删除函数**。当系统提示时，再次选择**删除**。

**删除相关联的 IAM 资源**

1. 通过以下网址打开 IAM 控制台：[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 从**详细信息**中，选择**角色**。

1. 从角色列表中选择 **GetStartedLambdaIntegrationRole**，再选择**角色操作**，然后选择**删除角色**。按照控制台中的步骤删除该角色。

# 教程：利用跨账户 Lambda 代理集成创建 REST API
<a name="apigateway-cross-account-lambda-integrations"></a>

您现在可以使用其他 AWS Lambda 账户中的 AWS 函数作为 API 集成后端。每个账户都可以位于 Amazon API Gateway 可用的任何区域中。这样便可轻松地跨多个 API 集中管理和共享 Lambda 后端函数。

在本节中，我们将介绍如何使用 Amazon API Gateway 控制台配置跨账户 Lambda 代理集成。

## 为 API Gateway 跨账户 Lambda 集成创建 API
<a name="apigateway-cross-account-lambda-integrations-create-api"></a>

**创建 API**

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

1. 如果您是第一次使用 API Gateway，您会看到一个介绍服务特征的页面。在 **REST API** 下，选择**生成**。当**创建示例 API** 弹出框出现时，选择**确定**。

   如果这不是您首次使用 API Gateway，请选择**创建 API**。在 **REST API** 下，选择**生成**。

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

1. （可选）对于**描述**，输入描述。

1. 将 **API 端点类型**设置保留为**区域**。

1. 为 **IP 地址类型**选择 **IPv4**。

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

## 在另一个账户中创建 Lambda 集成函数
<a name="apigateway-cross-account-lambda-integrations-create-lambda-function"></a>

现在，您将在与创建示例 API 不同的账户中创建 Lambda 函数。

**在另一个账户中创建 Lambda 函数**

1. 从与创建 API Gateway API 不同的账户登录 Lambda 控制台。

1. 选择**创建函数**。

1. 选择**从头开始创作**。

1. 在**从头开始创作**下，执行以下操作：

   1. 对于**函数名称**，输入一个名称。

   1. 从**运行时**下拉列表中，选择受支持的 Node.js 运行时。

   1. 对于**架构**，请保留默认设置。

   1. 在**权限**下，展开**选择或创建执行角色**。您可以创建角色或选择现有角色。

   1. 选择**创建函数**以继续。

1. 向下滚动到**函数代码**窗格。

1. 输入来自 [教程：利用 Lambda 代理集成创建 REST API](api-gateway-create-api-as-simple-proxy-for-lambda.md) 的 Node.js 函数实现。

1. 选择 **Deploy (部署)**。

1. 记下函数的完整 ARN（位于 Lambda 函数窗格的右上角）。当您创建跨账户 Lambda 集成时，将需要此信息。

## 配置跨账户 Lambda 集成
<a name="apigateway-cross-account-lambda-integrations-create-integration2"></a>

一旦您在其他账户中拥有 Lambda 集成函数，就可以使用 API Gateway 控制台将其添加到第一个账户中的 API。

**注意**  
如果要配置跨区域、跨账户授权方，则添加到目标函数的 `sourceArn` 应使用此函数的区域，而不是 API 的区域。

创建 API 后，您将创建一个资源。通常情况下，根据应用程序逻辑将 API 资源组织成资源树形式。在本示例中，您将创建一个 **/helloworld** 资源。

**创建资源**

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

1. 将**代理资源**保持为关闭状态。

1. 将**资源路径**保持为 `/`。

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

1. 将 **CORS（跨源资源共享）**保持为关闭状态。

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

创建资源后，您将创建一个 `GET` 方法。您将此 `GET` 方法与另一个账户中的 Lambda 函数集成。

**创建 `GET` 方法**

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

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

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

1. 打开 **Lambda 代理集成**。

1. 对于 **Lambda 函数**，输入步骤 1 中您的 Lambda 函数的完整 ARN。

   在 Lambda 控制台中，您可以在控制台窗口的右上角找到函数的 ARN。

1. 当您输入 ARN 时，将出现一个 `aws lambda add-permission` 命令字符串。此策略将向您的第一个账户授予对第二个账户的 Lambda 函数的访问权限。将 `aws lambda add-permission` 命令字符串复制粘贴到为您的第二个账户配置的 AWS CLI 窗口中。

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

您可以在 Lambda 控制台中查看您的函数更新后的策略。

**（可选）查看更新后的策略**

1. 登录到 AWS 管理控制台，然后通过以下网址打开 AWS Lambda 控制台：[https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/)。

1. 选择您的 Lambda 函数。

1. 选择**权限**。

   您应该看到具有 `Allow` 子句的 `Condition` 策略，其中 `AWS:SourceArn` 是您 API 的 `GET` 方法的 ARN。