Amazon API Gateway
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

教程:通过两个 AWS 服务集成和一个 Lambda 非代理集成创建 Calc REST API

非代理集成教程入门完全使用 Lambda Function 集成。Lambda Function 集成是 AWS Service 集成类型的特殊情况,该类型可为您执行大量集成设置,如自动添加所需的基于资源的权限以调用 Lambda 函数。在这里,三个集成中的两个集成使用的是 AWS Service 集成。在此集成类型中,您将具有更多控制,但您将需要手动执行任务,如创建和指定包含相应权限的 IAM 角色。

在本教程中,您将创建一个 Calc Lambda 函数,该函数可实施算术运算,同时接受 JSON 格式的输入和输出。然后,您将采用以下方式创建一个 REST API 并将其与 Lambda 函数集成:

  1. 通过在 /calc 资源上公开 GET 方法以调用 Lambda 函数,同时提供输入作为查询字符串参数。(AWS Service 集成)

  2. 通过在 /calc 资源上公开 POST 方法以调用 Lambda 函数,同时在方法请求负载中提供输入。(AWS Service 集成)

  3. 通过在嵌套的 /calc/{operand1}/{operand2}/{operator} 资源上公开 GET 以调用 Lambda 函数,同时提供输入作为路径参数。(Lambda Function 集成)

除了尝试使用本教程外,您可能还希望研究 Calc API 的 OpenAPI 定义文件,您可通过按照 将 REST API 导入 API Gateway 中 中的说明操作来将其导入 API Gateway 中。

创建 AWS 账户

在开始本教程之前,您将需要一个 AWS 账户。

如果您没有 AWS 账户,请通过以下步骤创建一个账户。

注册 AWS

  1. 打开 http://www.amazonaws.cn/,然后选择 Create an AWS Account

  2. 按照屏幕上的说明进行操作。

创建一个可代入的 IAM 角色

为了确保您的 API 调用您的 Calc Lambda 函数,您将需要具有一个 API Gateway 可代入的 IAM 角色,这是一个具有以下信任关联的 IAM 角色:

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

您创建的角色将需要具有 Lambda InvokeFunction 权限。否则,API 调用方将收到 500 Internal Server Error 响应。要向该角色提供此权限,请将以下 IAM 策略附加到它:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "*" } ] }

以下是完成所有操作的方式:

创建一个 API Gateway 可代入的 IAM 角色

  1. 登录到 IAM 控制台。

  2. 选择 Roles (角色)

  3. 选择 Create Role (创建角色)

  4. 选择受信任实体的类型下,选择 AWS 服务

  5. 选择将使用此角色的服务下,选择 Lambda

  6. 选择 Next: Permissions (下一步:权限)

  7. 选择 Create Policy

    新的 Create Policy (创建策略) 控制台窗口将会打开。在该窗口中,执行以下操作:

    1. JSON 选项卡中,将现有策略替换为以下策略:

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "*" } ] }
    2. 选择查看策略

    3. Review Policy (查看策略) 下,执行以下操作:

      1. 对于 Name (名称),键入一个名称,如 lambda_execute

      2. 选择 Create Policy

  8. 在原来的 Create Role (创建角色) 控制台窗口中,执行以下操作:

    1. 从下拉列表的 Attach permissions policies (添加权限策略) 下,选择您的 lambda_execute 策略。

      如果您未在策略列表中看到您的策略,请选择列表顶部的刷新按钮。(请勿刷新浏览器页面!)

    2. 选择 Next:Tags (下一步: 标签)

    3. 选择 Next:Review (下一步: 审核)

    4. 对于 Role name (角色名称),键入一个名称,如 lambda_invoke_function_assume_apigw_role

    5. 选择 Create role (创建角色)

  9. 从角色列表中,选择您的 lambda_invoke_function_assume_apigw_role

  10. 选择 Trust relationships (信任关系) 选项卡。

  11. 选择 Edit trust relationship (编辑信任关系)

  12. 使用以下策略替换现有策略:

    { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com", "apigateway.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }
  13. 选择 Update Trust Policy

  14. 请记下您刚刚创建的角色的角色 ARN。您以后将需要它。

创建 Calc Lambda 函数

接下来,使用 Lambda 控制台创建 Lambda 函数。

  1. 在 Lambda 控制台,选择 Create function (创建函数)

  2. 选择 Author from Scratch (从头开始创作)

  3. 对于 Name (名称),键入 Calc

  4. Runtime (运行时) 设置为 Node.js 8.10

  5. 选择 Create function (创建函数)

  6. 复制以下 Lambda 函数,并将其粘贴到 Lambda 控制台的代码编辑器中。

    console.log('Loading the Calc function'); exports.handler = function(event, context, callback) { console.log('Received event:', JSON.stringify(event, null, 2)); if (event.a === undefined || event.b === undefined || event.op === undefined) { callback("400 Invalid Input"); } var res = {}; res.a = Number(event.a); res.b = Number(event.b); res.op = event.op; if (isNaN(event.a) || isNaN(event.b)) { callback("400 Invalid Operand"); } switch(event.op) { case "+": case "add": res.c = res.a + res.b; break; case "-": case "sub": res.c = res.a - res.b; break; case "*": case "mul": res.c = res.a * res.b; break; case "/": case "div": res.c = res.b===0 ? NaN : Number(event.a) / Number(event.b); break; default: callback("400 Invalid Operator"); break; } callback(null, res); };
  7. 在“Execution (执行)”角色下,选择 Choose an existing role (选择现有角色)

  8. 输入您之前创建的 lambda_invoke_function_assume_apigw_role 角色的角色 ARN。

  9. 选择 Save (保存)

此函数需要来自 a 输入参数的两个操作数 (bop) 以及一个运算符 (event)。该输入是格式如下的 JSON 对象:

{ "a": "Number" | "String", "b": "Number" | "String", "op": "String" }

此函数会返回计算所得的结果 (c) 和输入。对于无效的输入,该函数将返回空值或“Invalid op”字符串作为结果。输出具有以下 JSON 格式:

{ "a": "Number", "b": "Number", "op": "String", "c": "Number" | "String" }

您应该先在 Lambda 控制台中测试该函数,然后再在下一步中将其与 API 集成。

测试 Calc Lambda 函数

以下是如何在 Lambda 控制台中测试您的 Calc 函数:

  1. Saved test events (已保存的测试事件) 下拉菜单中,选择 Configure test events (配置测试事件)

  2. 对于测试事件名称,请输入 calc2plus5

  3. 将测试事件定义替换为以下内容:

    { "a": "2", "b": "5", "op": "+" }
  4. 选择 Save (保存)

  5. 选择 Test (测试)

  6. 展开 Execution result: succeeded (执行结果: 成功)。您将看到以下内容:

    { "a": 2, "b": 5, "op": "+", "c": 7 }

创建 Calc API

以下过程介绍如何为您刚刚创建的 Calc Lambda 函数创建 API。在后续部分中,您将资源和方法添加到该 API。

创建 Calc API

  1. 在 API Gateway 控制台中,选择 Create API (创建 API)

  2. API Name (API 名称) 中,键入 LambdaCalc

  3. Description (描述) 留空,并将 Endpoint Type (终端节点类型) 设置为 Regional (区域)

  4. 选择 Create API (创建 API)

集成 1:创建使用查询参数的 GET 方法以调用 Lambda 函数

通过创建将查询字符串参数传递给 Lambda 函数的 GET 方法,启用要从浏览器中进行调用的 API。这种方法可能非常有用,特别是对于允许开放访问的 API。

设置使用查询字符串参数的 GET 方法

  1. 在 API Gateway 控制台中,在您的 LambdaCalc API 的 Resources (资源) 下,选择 /

  2. Actions (操作) 下拉菜单中,选择 Create Resource (创建资源)

  3. 对于 Resource Name (资源名称),输入 calc

  4. 选择 Create Resource (创建资源)

  5. 选择您刚刚创建的 /calc 资源。

  6. Actions (操作) 下拉菜单中,选择 Create Method (创建方法)

  7. 在出现的方法下拉菜单中,选择 GET

  8. 选择对勾图标以保存您的选择。

  9. 设置窗格中:

    1. 对于 Integration type (集成类型),选择 AWS 服务

    2. 选择您为 AWS 区域创建 Lambda 函数时所在的区域(例如 us-west-2)。

    3. 对于 AWS 服务,选择 Lambda

    4. AWS Subdomain (AWS 子域) 留空,因为我们的 Lambda 函数未托管在任何 AWS 子域上。

    5. 对于 HTTP 方法, 选择 POST,然后选择对勾图标以保存您的选择。Lambda 要求使用 POST 请求调用任何 Lambda 函数。此示例表明,前端方法请求中的 HTTP 方法可以与后端中的集成请求不同。

    6. Action Type (操作类型) 选择 Use path override。借助此选项,我们可以指定用来执行 Calc 函数的调用操作的 ARN。

    7. Path override (路径覆盖) 中输入 /2015-03-31/functions/arn:aws:lambda:region:account-id:function:Calc/invocations,其中 region 为您在其中创建 Lambda 函数的区域,account-id 是 AWS 账户的账号。

    8. 对于 Execution role (执行角色),输入您 之前lambda_invoke_function_assume_apigw_role IAM 角色创建的角色 ARN。

    9. Content Handling (内容处理) 设置保留为 Passthrough (传递),因为此方法不会处理任何二进制数据。

    10. Use default timeout (使用默认超时) 保持选中状态。

    11. 选择 Save (保存)

  10. 选择 Method Request (方法请求)

    现在,为 /calc 上的 GET 方法设置查询参数,以代表后端 Lambda 函数接收输入。

    1. 选择 Request Validator (请求验证程序) 旁的铅笔图标,从下拉菜单中,选择 Validate query string parameters and headers (验证查询字符串参数和标头)。如果客户端没有指定必需的参数,此设置将返回一个错误消息,表示缺少必需的参数。对后端的调用不会向您收费。

    2. 选择对勾图标以保存您的更改。

    3. 展开 URL Query String Parameters (URL 查询字符串参数) 部分。

    4. 选择 Add query string (添加查询字符串)

    5. 对于 Name (名称),键入 operand1

    6. 选择对勾图标保存参数。

    7. 要创建名为 operand2operator 的参数,请重复前面的步骤。

    8. 检查每个参数的 Required (必填) 选项,确保它们已通过验证。

  11. 选择 Method Execution (方法执行),然后选择 Integration Request (集成请求),以设置映射模板,将客户端提供的查询字符串转换为 Calc 函数需要的集成请求负载。

    1. 展开 Mapping Templates (映射模板) 部分。

    2. Request body passthrough (请求正文传递) 选择 When no template matches the request Content-Type header (当没有模板匹配请求的 Content-Type 标头时)

    3. Content-Type (内容-类型) 下,选择 Add mapping template (添加映射模板)

    4. 键入 application/json,选择复选标记图标以打开模板编辑器。

    5. 选择 Yes, secure this integration (是,锁定此集成) 以继续。

    6. 将以下映射脚本复制到映射模板编辑器中:

      { "a": "$input.params('operand1')", "b": "$input.params('operand2')", "op": "$input.params('operator')" }

      此模板会将 Method Request (方法请求) 中声明的三个查询字符串参数映射为 JSON 对象的指定属性值,作为后端 Lambda 函数的输入。转换后的 JSON 对象将作为集成请求负载包含在内。

    7. 选择 Save (保存)

  12. 选择 Method Execution (方法执行)

  13. 现在,您可以测试 GET 方法来验证它是否已经过正确设置,可以调用 Lambda 函数。

    1. 对于 Query Strings (查询字符串),键入 operand1=2&operand2=3&operator=+

    2. 选择 Test (测试)

      结果应与如下显示类似:

      
                                在 API Gateway 中创建 API 以作为 Lambda 代理

集成 2:创建使用 JSON 负载的 POST 方法以调用 Lambda 函数

通过创建使用 JSON 负载的 POST 方法以调用 Lambda 函数完成此操作,以便客户端必须将必要的输入提供给请求正文中的后端函数。为确保客户端上传正确的输入数据,您将对负载启用请求验证。

设置使用 JSON 负载的 POST 方法以调用 Lambda 函数

  1. 转到 API Gateway 控制台。

  2. 选择 API

  3. 选择您之前创建的 LambdaCalc API。

  4. Resources (资源) 窗格中,选择 /calc 资源。

  5. 操作菜单中,选择 Create Method (创建方法)

  6. 从方法下拉列表中选择 POST

  7. 选择对勾图标以保存您的选择。

  8. 设置窗格中:

    1. 对于 Integration type (集成类型),选择 AWS 服务

    2. 选择您为 AWS 区域创建 Lambda 函数时所在的区域(例如 us-west-2)。

    3. 对于 AWS 服务,选择 Lambda

    4. AWS Subdomain (AWS 子域) 留空,因为我们的 Lambda 函数未托管在任何 AWS 子域上。

    5. 对于 HTTP method (HTTP 方法),选择 POST。此示例表明,前端方法请求中的 HTTP 方法可以与后端中的集成请求不同。

    6. 对于 Action (操作),针对 Action Type (操作类型),选择 Use path override。借助此选项,我们可以指定用来执行 Calc 函数的调用操作的 ARN。

    7. 对于 Path override (路径覆盖),键入 /2015-03-31/functions/arn:aws:lambda:region:account-id:function:Calc/invocations,其中 region 为您在其中创建 Lambda 函数的区域,account-id 为 AWS 账户的账号。

    8. 对于 Execution role (执行角色),输入您 之前lambda_invoke_function_assume_apigw_role IAM 角色创建的角色 ARN。

    9. Content Handling (内容处理) 设置保留为 Passthrough (传递),因为此方法不会处理任何二进制数据。

    10. Use Default Timeout (使用默认超时) 保持选中状态。

    11. 选择 Save (保存)

  9. 在 API Gateway 控制台的主导航窗格的 LambdaCalc API 下选择 Models (模型),为方法的输入和输出创建数据模型:

    1. Models (模型) 窗格中,选择 Create (创建)。在 Model name (模型名称) 中键入 Input,在 Content type (内容类型) 中键入 application/json,并将以下架构定义复制到 Model schema (模型架构) 框中:

      { "type":"object", "properties":{ "a":{"type":"number"}, "b":{"type":"number"}, "op":{"type":"string"} }, "title":"Input" }

      此模型描述了输入数据结构,将用于验证传入请求正文。

    2. 选择 Create model (创建模型)

    3. Models (模型) 窗格中,选择 Create (创建)。在 Model name (模型名称) 中键入 Output,在 Content type (内容类型) 中键入 application/json,并将以下架构定义复制到 Model schema (模型架构) 框中:

      { "type":"object", "properties":{ "c":{"type":"number"} }, "title":"Output" }

      此模型描述了后端计算得出的输出的数据结构。它可用于将集成响应数据映射到不同的模型。本教程依靠传递行为,并不会使用此模型。

    4. 在控制台屏幕顶部为您的 API 找到 API ID 并记下它。它会显示在 API 名称后的圆括号中。

    5. Models (模型) 窗格中,选择 Create (创建)

    6. Model name (模型名称) 中键入 Result

    7. Content type (内容类型) 中键入 application/json

    8. 将以下架构定义(其中 restapi-id 为您之前记下的 REST API ID)复制到 Model schema (模型架构) 框中:

      { "type":"object", "properties":{ "input":{ "$ref":"https://apigateway.amazonaws.com/restapis/restapi-id/models/Input" }, "output":{ "$ref":"https://apigateway.amazonaws.com/restapis/restapi-id/models/Output" } }, "title":"Output" }

      此模型描述了返回响应数据的数据结构。它会引用指定 API (Input) 中定义的 Outputrestapi-id 架构。再次重申,这一模型并未在本教程中使用,因为本教程利用了传递行为。

    9. 选择 Create model (创建模型)

  10. 在主导航窗格的 LambdaCalc API 下,选择 Resources (资源)

  11. Resources (资源) 窗格中,为您的 API 选择 POST 方法。

  12. 选择 Method Request (方法请求)

  13. Method Request (方法请求) 配置设置中,执行以下操作,以对传入请求正文启用请求验证:

    1. 选择 Request Validator (请求验证程序) 旁的铅笔图标以选择 Validate body。选择对勾图标以保存您的选择。

    2. 展开 Request Body (请求正文) 部分,选择 Add model (添加模型)

    3. Content-Type (内容-类型) 输入字段中键入 application/json,然后在 Model name (模型名称) 列的下拉列表中选择 Input。选择对勾图标以保存您的选择。

  14. 要测试您的 POST 方法,请执行以下操作:

    1. 选择 Method Execution (方法执行)

    2. 选择 Test (测试)

  15. 将以下 JSON 负载复制到 Request Body (请求正文)

    { "a": 1, "b": 2, "op": "+" }
  16. 选择 Test (测试)

    Response Body (请求正文) 中,您应看到以下输出:

    { "a": 1, "b": 2, "op": "+", "c": 3 }

集成 3:创建使用路径参数的 GET 方法以调用 Lambda 函数

现在,您将在由一系列路径参数指定的资源上创建一个 GET 方法,以调用后端 Lambda 函数。路径参数值指定 Lambda 函数的输入数据。您将使用映射模板,将传入路径参数值映射到必需的集成请求负载。

此时,您将在 API Gateway 控制台中使用内置的 Lambda 集成支持来设置方法集成。

生成的 API 资源结构将如下所示:


                在 API Gateway 中创建 API 以作为 Lambda 代理

要设置 GET 方法,URL 路径参数

  1. 转到 API Gateway 控制台。

  2. API 下,选中您之前创建的 LambdaCalc API。

  3. 在 API 的资源导航窗格中,选择 /calc

  4. Actions (操作) 下拉菜单中,选择 Create Resource (创建资源)

  5. 对于 Resource Name (资源名称),键入 {operand1}

  6. 对于 Resource Path (资源路径),键入 {operand1}

  7. 选择 Create Resource (创建资源)

  8. 选择您刚创建的 /calc/{operand1} 资源。

  9. Actions (操作) 下拉菜单中,选择 Create Resource (创建资源)

  10. 对于 Resource Name (资源名称),键入 {operand2}

  11. 对于 Resource Path (资源路径),键入 {operand2}

  12. 选择 Create Resource (创建资源)

  13. 选择您刚创建的 /calc/{operand1}/{operand2} 资源。

  14. Actions (操作) 下拉菜单中,选择 Create Resource (创建资源)

  15. 对于 Resource Path (资源路径),键入 {operator}

  16. 对于 Resource Name (资源名称),键入 {operator}

  17. 选择 Create Resource (创建资源)

  18. 选择您刚创建的 /calc/{operand1}/{operand2}/{operator} 资源。

  19. 操作下拉菜单中,选择 Create Method (创建方法)

  20. 从方法下拉菜单中,选择 GET

  21. 设置窗格中,为 Integration type (集成类型) 选择 Lambda Function 以使用控制台支持的精简设置过程。

  22. Lambda 区域 选择一个区域(例如 us-west-2)。这是托管 Lambda 函数的区域。

  23. Lambda 函数 选择您的现有 Lambda 函数(例如 Calc)。

  24. 选择 Save (保存),然后选择 OK (确定) 以同意 Add Permissions to Lambda Function (将权限添加至 Lambda 函数)

  25. 选择 Integration Request (集成请求)

  26. 按如下所示设置映射模板:

    1. 展开 Mapping Templates (映射模板) 部分。

    2. 设置为 When no template matches the requested Content-Type header (当没有模板匹配请求的 Content-Type 标头时)

    3. 选择 Add mapping template (添加映射模板)

    4. Content-Type (内容-类型) 键入 application/json,然后选择对勾图标以打开模板编辑器。

    5. 选择 Yes, secure this integration (是,锁定此集成) 以继续。

    6. 将以下映射脚本复制到模板编辑器中:

      { "a": "$input.params('operand1')", "b": "$input.params('operand2')", "op": #if($input.params('operator')=='%2F')"/"#{else}"$input.params('operator')"#end }

      此模板会将创建 /calc/{operand1}/{operand2}/{operator} 资源时声明的三个 URL 路径参数映射为 JSON 对象中的指定属性值。由于 URL 路径必须经过 URL 编码,必须将除法运算符指定为 %2F,而不是 /。此模板先将 %2F 转换为 '/',然后再将其发送到 Lambda 函数。

    7. 选择 Save (保存)

    如果方法设置正确,这些设置应类似于以下内容:

    
                        设置使用路径参数的 GET 方法以调用 Lambda 函数
  27. 要测试您的 GET 函数,请执行以下操作:

    1. 选择 Method Execution (方法执行)

    2. 选择 Test (测试)

    3. {operand1}{operand2}{operator} 字段中,分别键入 12+

    4. 选择 Test (测试)

    5. 结果应该如下所示:

      
                                将方法请求 URL 路径参数映射到集成请求负载以调用 Lambda 函数

    此测试结果显示了后端 Lambda 函数的原始输出,它在不映射的情况下传递了集成响应,因为没有任何映射模板。接下来,您将在 Result 架构之后对方法响应负载的数据结构进行建模。

  28. 默认情况下,系统会为方法响应正文分配一个空白模型。这将在不映射的情况下传递集成响应正文。但是,当您为一种强类型语言(例如 Java 或 Objective-C)生成一个开发工具包时,您的开发工具包用户会收到一个空白对象作为结果。为确保 REST 客户端和开发工具包客户端能收到期望的结果,您必须使用预定义的架构为响应数据建模。在这里,您将为方法响应正文定义一个模型,并构建一个映射模板,以便将集成响应正文转换为方法响应正文。

    1. 选择 /calc/{operand1}/{operand2}/{operator}

    2. 选择 GET

    3. 选择 Method Execution (方法执行)

    4. 选择 Method Response (方法响应)

    5. 展开 200 响应,

    6. Response Body for 200 (200 的响应正文) 下,选择 application/json 内容类型对应的模型旁的铅笔图标。

    7. 模型下拉列表中,选择 Result

    8. 选择对勾图标以保存您的选择。

    为方法响应正文设置模型可以确保将响应数据转换为给定开发工具包的 Result 对象。要确保对集成响应数据进行相应的映射,您将需要一个映射模板。

  29. 要创建映射模板,请执行以下操作:

    1. 选择 Method Execution (方法执行)

    2. 选择 Integration Response (集成响应) 并展开 200 方法响应条目。

    3. 展开 Mapping Templates (映射模板) 部分。

    4. Content-Type (内容-类型) 列表中选择 application/json

    5. Generate template (生成模板) 下拉列表中选择 Result,以显示 Result 模板蓝图。

    6. 将模板蓝图更改为以下内容:

      #set($inputRoot = $input.path('$')) { "input" : { "a" : $inputRoot.a, "b" : $inputRoot.b, "op" : "$inputRoot.op" }, "output" : { "c" : $inputRoot.c } }
    7. 选择 Save (保存)

  30. 要测试映射模板,请执行以下操作:

    1. 选择 Method Execution (方法执行)

    2. 选择 Test (测试)

    3. operand1operand2operator 输入字段中,分别键入 12+

      现在,Lambda 函数的集成响应已映射到 Result 对象。

    4. 选择 Test (测试),您将在控制台中的 Response Body (响应正文) 下看到以下内容:

      { "input": { "a": 1, "b": 2, "op": "+" }, "output": { "c": 3 } }
  31. 此时,API 在 API Gateway 控制台中只能通过 Test Invoke (测试调用) 进行调用。要使其可用于客户端,您将需要按以下方式部署它:

    1. Actions (操作) 下拉菜单中选择 Deploy API (部署 API)

    2. Deployment Stage (部署阶段) 下拉菜单中选择 [New Stage]

    3. 对于 Stage Name (阶段名称),输入 test

    4. 选择 Deploy (部署)

    5. 请记下控制台窗口顶部的 Invoke URL (调用 URL)。您可以将此值与 PostmancURL 等工具结合使用来测试您的 API。

注意

每当您添加、修改或删除资源和方法、更新数据映射或者更新阶段设置时,请始终确保重新部署 API。否则,新功能或更新将不可用于您的 API 的客户端。