将 Amazon Lambda 与 Amazon API Gateway 结合使用 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

将 Amazon Lambda 与 Amazon API Gateway 结合使用

您可以使用 Amazon API Gateway 为 Lambda 函数创建带有 HTTP 端点的 Web API。API Gateway 提供工具,用于创建和记录向 Lambda 函数路由 HTTP 请求的 Web API。您可以使用身份验证和授权控制来保护对 API 的访问。您的 API 可以通过互联网传输流量,也可以仅允许在您的 VPC 内访问。

API 中的资源会定义一个或多个方法,如 GET 或 POST。方法具有将请求传送给 Lambda 函数或其他集成类型的集成。您可以单独定义每个资源和方法,也可以使用特定的资源和方法类型来匹配属于特定模式的所有请求。代理资源会捕获某个资源下的所有路径。ANY 方法会捕获所有 HTTP 方法。

本节介绍有关如何选择 API 类型、向 Lambda 函数添加端点的一般信息,以及有关事件、权限、响应和错误处理的信息。

向 Lambda 函数添加终端节点

向 Lambda 函数添加公有端点
  1. 打开 Lamba 控制台的 Functions(函数)页面。

  2. 选择函数。

  3. Function overview(函数概览)下,选择 Add trigger(添加触发器)。

  4. 选择 API Gateway (API 网关)

  5. 选择 Create an API(创建 API)或 Use an existing API(使用现有 API)。

    1. New API(新 API):对于 API type(API 类型),请选择 HTTP API。有关更多信息,请参阅 API 类型

    2. Existing API(现有 API):从下拉菜单中选择 API 或输入 API ID(例如,r3pmxmplak)。

  6. 对于 Security (安全性),请选择 Open (打开)

  7. 选择添加

代理集成

API Gateway API 由阶段、资源、方法和集成组成。阶段和资源决定终端节点的路径:

API 路径格式
  • /prod/prod 阶段和根资源。

  • /prod/userprod 阶段和 user 资源。

  • /dev/{proxy+}dev 阶段中的路线。

  • / – (HTTP API) 默认阶段和根资源。

Lambda 集成将路径和 HTTP 方法的组合映射到 Lambda 函数。您可以将 API Gateway 配置为按原样(自定义集成)传递 HTTP 请求体,或者将请求正文封装在包含所有请求信息(包括标头、资源、路径和方法)的文档中。

事件格式

Amazon API Gateway 会使用包含 HTTP 请求的 JSON 表示形式的事件同步调用函数。对于自定义集成,该事件为请求的正文。对于代理集成,该事件具有已确定的结构。以下示例显示了来自 API Gateway REST API 的代理事件。

event.json API Gateway 代理事件 (REST API)
{ "resource": "/", "path": "/", "httpMethod": "GET", "requestContext": { "resourcePath": "/", "httpMethod": "GET", "path": "/Prod/", ... }, "headers": { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "accept-encoding": "gzip, deflate, br", "Host": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", "X-Amzn-Trace-Id": "Root=1-5e66d96f-7491f09xmpl79d18acf3d050", ... }, "multiValueHeaders": { "accept": [ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" ], "accept-encoding": [ "gzip, deflate, br" ], ... }, "queryStringParameters": null, "multiValueQueryStringParameters": null, "pathParameters": null, "stageVariables": null, "body": null, "isBase64Encoded": false }

响应格式

API Gateway 会等待函数响应并将结果转发给调用方。对于自定义集成,您可以定义集成响应和方法响应,以将函数的输出转换为 HTTP 响应。对于代理集成,函数必须以特定格式的响应形式来做出响应。

以下示例显示了来自 Node.js 函数的响应对象。该响应对象表示包含 JSON 文档的成功 HTTP 响应。

index.mjs:代理集成响应对象(Node.js)
var response = { "statusCode": 200, "headers": { "Content-Type": "application/json" }, "isBase64Encoded": false, "multiValueHeaders": { "X-Custom-Header": ["My value", "My other value"], }, "body": "{\n \"TotalCodeSize\": 104330022,\n \"FunctionCount\": 26\n}" }

Lambda 运行时会将响应对象序列化为 JSON 并将其发送给 API。此 API 会解析该响应并用它来创建 HTTP 响应,然后再将其发送到发出原始请求的客户端。

例 HTTP 响应
< HTTP/1.1 200 OK < Content-Type: application/json < Content-Length: 55 < Connection: keep-alive < x-amzn-RequestId: 32998fea-xmpl-4268-8c72-16138d629356 < X-Custom-Header: My value < X-Custom-Header: My other value < X-Amzn-Trace-Id: Root=1-5e6aa925-ccecxmplbae116148e52f036 < { "TotalCodeSize": 104330022, "FunctionCount": 26 }

权限

Amazon API Gateway 将从函数的基于资源的策略获取调用函数的权限。您可以授予对整个 API 的调用权限,也可以仅授予对某个阶段、资源或方法的有限访问权限。

当您使用 Lambda 控制台、API Gateway 控制台或 Amazon SAM 模板向函数添加 API 时,会自动更新函数的基于资源的策略。以下是一个示例函数策略。

例 函数策略
{ "Version": "2012-10-17", "Id": "default", "Statement": [ { "Sid": "nodejs-apig-functiongetEndpointPermissionProd-BWDBXMPLXE2F", "Effect": "Allow", "Principal": { "Service": "apigateway.amazonaws.com" }, "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:us-east-2:111122223333:function:nodejs-apig-function-1G3MXMPLXVXYI", "Condition": { "StringEquals": { "aws:SourceAccount": "111122223333" }, "ArnLike": { "aws:SourceArn": "arn:aws:execute-api:us-east-2:111122223333:ktyvxmpls1/*/GET/" } } } ] }

您可以通过以下 API 操作手动管理函数策略权限:

使用 add-permission 命令,可授予对现有 API 的调用权限。

aws lambda add-permission --function-name my-function \ --statement-id apigateway-get --action lambda:InvokeFunction \ --principal apigateway.amazonaws.com.cn \ --source-arn "arn:aws:execute-api:cn-north-1:123456789012:mnh1xmpli7/default/GET/"

您应看到以下输出:

{ "Statement": "{\"Sid\":\"apigateway-test-2\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com.cn\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:cn-north-1:123456789012:function:my-function\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:cn-north-1:123456789012:mnh1xmpli7/default/GET\"}}}" }
注意

如果您的函数和 API 位于不同的区域,则源 ARN 中的区域标识符必须与函数的区域(而不是 API 的区域)匹配。当 API Gateway 调用函数时,它会使用基于 API 的 ARN 的资源 ARN,但该资源 ARN 已被修改为与函数的区域相匹配。

此示例中的源 ARN 授予对 API 默认阶段根资源 GET 方法的集成的权限,其 ID为 mnh1xmpli7。您可以在源 ARN 中使用星号授予对多个阶段、方法或资源的权限。

资源模式
  • mnh1xmpli7/*/GET/* – 对所有阶段中的所有资源调用 GET 方法。

  • mnh1xmpli7/prod/ANY/user – 对 prod 阶段中的 user 资源调用 ANY 方法。

  • mnh1xmpli7/*/*/* – 对所有阶段中的所有资源调用 ANY 方法。

有关查看策略和删除语句的详细信息,请参阅清除基于资源的策略

利用 API Gateway API 处理错误

API Gateway 将所有调用和函数错误视为内部错误。如果 Lambda API 拒绝调用请求,API Gateway 会返回 500 错误代码。如果函数运行但返回错误,或返回格式错误的响应,API Gateway 会返回 502。在这两种情况下,来自 API Gateway 的响应的正文都是 {"message": "Internal server error"}

注意

API Gateway 不会重试 Lambda 调用。如果 Lambda 返回错误,API Gateway 会向客户端返回错误响应。

以下示例显示导致 API Gateway 中出现函数错误和 502 的请求的 X-Ray 跟踪映射。客户端收到通用错误消息。


        使用 API Gateway 跟踪函数错误的映射。

要自定义错误响应,您必须捕获代码中的错误并以所需格式设置响应的格式。

index.mjs:格式设置错误
var formatError = function(error){ var response = { "statusCode": error.statusCode, "headers": { "Content-Type": "text/plain", "x-amzn-ErrorType": error.code }, "isBase64Encoded": false, "body": error.code + ": " + error.message } return response }

API Gateway 将此响应转换为带有自定义状态代码和正文的 HTTP 错误。在跟踪映射中,函数节点为绿色,因为它处理了错误。


        使用 API Gateway 跟踪格式化错误的映射。

选择 API 类型

API Gateway 支持三种可调用 Lambda 函数的 API 类型:

  • HTTP API – 一种轻量级的低延迟 RESTful API。

  • REST API – 一种功能丰富的可定制 RESTful API。

  • WebSocket API — 一种 Web API,它与客户端保持持久连接,以实现全双工通信。

HTTP API 和 REST API 都是用于处理 HTTP 请求并返回响应的 RESTful API。HTTP API 后推出,是使用 API Gateway 版本 2 API 构建的。以下是 HTTP API 的新功能:

HTTP API 功能
  • 自动部署 – 当您修改路线或集成时,更改会自动部署到启用了自动部署的阶段。

  • 默认阶段 – 您可以创建默认阶段 ($default),以便在 API URL 的根路径处提供请求。对于具名阶段,必须在路径的开头包含阶段名称。

  • CORS 配置 – 您可以配置 API,使其将 CORS 标头添加到传出响应中,而不是在函数代码中手动添加。

REST API 是 API Gateway 自发布起就支持的典型 RESTful API。REST API 现在具有更多的自定义、集成和管理功能。

REST API 功能
  • 集成类型 – REST API 支持自定义 Lambda 集成。使用自定义集成,您可以直接将请求正文发送到函数,也可以对其应用转换模板,然后再发送到函数。

  • 访问控制 – REST API 支持更多身份验证和授权选项。

  • 监控和跟踪 – REST API 支持 Amazon X-Ray 跟踪和其他日志记录选项。

有关详细比较,请参阅 API Gateway 开发人员指南中的在 HTTP API 和 REST API 之间选择

WebSocket API 还使用 API Gateway 第 2 版 API,并支持类似的功能集。对于受益于客户端和 WebSocket API 之间持久连接的应用程序,请使用 API。 WebSocket API 提供全双工通信,这意味着客户端和 API 都可以在不等待响应的情况下连续发送消息。

HTTP API 支持简化的事件格式(2.0 版)。以下示例显示了来自 HTTP API 的事件。

event-v2.json – API Gateway 代理事件 (HTTP API)
{ "version": "2.0", "routeKey": "ANY /nodejs-apig-function-1G3XMPLZXVXYI", "rawPath": "/default/nodejs-apig-function-1G3XMPLZXVXYI", "rawQueryString": "", "cookies": [ "s_fid=7AABXMPL1AFD9BBF-0643XMPL09956DE2", "regStatus=pre-register" ], "headers": { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "accept-encoding": "gzip, deflate, br", ... }, "requestContext": { "accountId": "123456789012", "apiId": "r3pmxmplak", "domainName": "r3pmxmplak.execute-api.us-east-2.amazonaws.com", "domainPrefix": "r3pmxmplak", "http": { "method": "GET", "path": "/default/nodejs-apig-function-1G3XMPLZXVXYI", "protocol": "HTTP/1.1", "sourceIp": "205.255.255.176", "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36" }, "requestId": "JKJaXmPLvHcESHA=", "routeKey": "ANY /nodejs-apig-function-1G3XMPLZXVXYI", "stage": "default", "time": "10/Mar/2020:05:16:23 +0000", "timeEpoch": 1583817383220 }, "isBase64Encoded": true }

有关更多信息,请参阅 API Gateway 开发人员指南中的 Amazon Lambda 集成

示例应用程序

本指南的 GitHub 存储库为 API Gateway 提供了以下 API Gateway 的示例应用程序。

  • 带有 Node.js 的 API Gateway – 具有 Amazon SAM 模板的函数,该模板可用于创建启用了 Amazon X-Ray 跟踪的 REST API。它包含用于部署和调用函数、测试 API 以及执行清理的脚本。

Lambda 还提供了蓝图模板,您可以使用这些蓝图和模板在 Lambda 控制台中创建 API Gateway 应用程序。