使用 Amazon API Gateway 端点调用 Lambda 函数 - AWS Lambda

使用 Amazon API Gateway 端点调用 Lambda 函数

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

API 中的资源会定义一个或多个方法,如 GET 或 POST。方法具有将请求传送给 Lambda 函数或其他集成类型的集成。您可以单独定义每个资源和方法,也可以使用特定的资源和方法类型来匹配属于特定模式的所有请求。代理资源会捕获某个资源下的所有路径。ANY 方法会捕获所有 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 支持 AWS X-Ray 跟踪和其他日志记录选项。

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

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

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

例 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 中的 HTTP API 创建 AWS 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. 现有 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 请求体,或者将请求正文封装在包含所有请求信息(包括标头、资源、路径和方法)的文档中。

有关更多信息,请参阅 API Gateway 中的 Lambda 代理集成

事件格式

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

例 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 控制台或 AWS 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 \ --source-arn "arn:aws:execute-api:us-east-2:123456789012:mnh1xmpli7/default/GET/"

您应看到以下输出:

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

如果您的函数和 API 位于不同的 AWS 区域,则源 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 方法。

有关查看策略和删除语句的详细信息,请参阅在 Lambda 中使用基于资源的 IAM 策略

示例应用程序

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