本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
将 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 函数添加端点的一般信息,以及有关事件、权限、响应和错误处理的信息。
Sections
向 Lambda 函数添加终端节点
向 Lambda 函数添加公有端点
打开 Lamba 控制台的 Functions
(函数)页面。 -
选择函数。
-
在 Function overview(函数概览)下,选择 Add trigger(添加触发器)。
-
选择 API Gateway (API 网关)。
-
选择 Create an API(创建 API)或 Use an existing API(使用现有 API)。
-
New API(新 API):对于 API type(API 类型),请选择 HTTP API。有关更多信息,请参阅 API 类型。
-
Existing API(现有 API):从下拉菜单中选择 API 或输入 API ID(例如,r3pmxmplak)。
-
-
对于 Security (安全性),请选择 Open (打开)。
-
选择添加。
代理集成
API Gateway API 由阶段、资源、方法和集成组成。阶段和资源决定终端节点的路径:
API 路径格式
-
/prod/
–prod
阶段和根资源。 -
/prod/user
–prod
阶段和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 跟踪映射。客户端收到通用错误消息。
要自定义错误响应,您必须捕获代码中的错误并以所需格式设置响应的格式。
例 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 类型
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 应用程序。