【问题标题】:Why does API Gateway (Test) not wait for async lambda?为什么 API Gateway (Test) 不等待异步 lambda?
【发布时间】:2021-06-23 01:20:08
【问题描述】:

我正在使用 Node.js (14.x) 在 AWS 上编写异步 lambda。此 lambda 由 API 网关调用(REST API、POST 方法、已启用 CORS)。

为了允许 API 网关调用异步 lambda,我在其集成请求中添加了以下 HTTP 标头:名称 = X-Amz-Invocation-Type 和映射自(值)= 'Event' as specified here

当我运行测试时,我得到以下输出:

Execution log for request BLAH
Fri Mar 26 07:30:34 UTC 2021 : Starting execution for request: BLAH
Fri Mar 26 07:30:34 UTC 2021 : HTTP Method: POST, Resource Path: BLAH
Fri Mar 26 07:30:34 UTC 2021 : Method request path: {}
Fri Mar 26 07:30:34 UTC 2021 : Method request query string: {}
Fri Mar 26 07:30:34 UTC 2021 : Method request headers: {}
Fri Mar 26 07:30:34 UTC 2021 : Method request body before transformations: {
  "id": "BLAH",
  "recaptcha": "BLAH"
}
Fri Mar 26 07:30:34 UTC 2021 : Request validation succeeded for content type application/json
Fri Mar 26 07:30:34 UTC 2021 : Endpoint request URI: https://lambda.BLAH.amazonaws.com/2015-03-31/functions/arn:aws:lambda:BLAH:function:BLAH/invocations
Fri Mar 26 07:30:34 UTC 2021 : Endpoint request headers: {X-Amz-Date=BLAH, x-amzn-apigateway-api-id=BLAH, Accept=application/json, User-Agent=AmazonAPIGateway_BLAH, Host=lambda.BLAH.amazonaws.com, X-Amz-Content-Sha256=BLAH, X-Amzn-Trace-Id=Root=BLAH, x-amzn-lambda-integration-tag=BLAH, Authorization=*****BLAH*****, X-Amz-Source-Arn=arn:aws:execute-api:BLAH/test-invoke-stage/POST/BLAH, X-Amz-Invocation-Type=Event, X-Amz-Security-Token=BLAH [TRUNCATED]
Fri Mar 26 07:30:34 UTC 2021 : Endpoint request body after transformations: {
  "id": "BLAH",
  "recaptcha": "BLAH"
}
Fri Mar 26 07:30:34 UTC 2021 : Sending request to https://lambda.BLAH.amazonaws.com/2015-03-31/functions/arn:aws:lambda:BLAH:function:BLAH/invocations
Fri Mar 26 07:30:34 UTC 2021 : Received response. Status: 202, Integration latency: 34 ms
Fri Mar 26 07:30:34 UTC 2021 : Endpoint response headers: {Date=Fri, 26 Mar 2021 07:30:34 GMT, Content-Length=0, Connection=keep-alive, x-amzn-RequestId=BLAH, x-amzn-Remapped-Content-Length=0, X-Amzn-Trace-Id=root=BLAH;sampled=0}
Fri Mar 26 07:30:34 UTC 2021 : Endpoint response body before transformations: 
Fri Mar 26 07:30:34 UTC 2021 : Method response body after transformations: 
Fri Mar 26 07:30:34 UTC 2021 : Method response headers: {X-Amzn-Trace-Id=Root=BLAH;Sampled=0, Access-Control-Allow-Origin=*, Content-Type=application/json}
Fri Mar 26 07:30:34 UTC 2021 : Successfully completed execution

请注意,响应给出了Status: 202,并且没有响应正文。 无论我在 lambda 中放入什么代码,似乎都是这样。以下是我尝试过的几个基本示例:

// Load the AWS SDK for Node.js and set the region.
var AWS = require('aws-sdk');
AWS.config.update({region: 'BLAH'});

// Main function, responds to AWS API Gateway.
exports.handler = async function (event, context) {
    var response = {
        httpStatus : 200,
        message : "Success"
    };
    return JSON.stringify(response);
};

// Load the AWS SDK for Node.js and set the region.
var AWS = require('aws-sdk');
AWS.config.update({region: 'BLAH'});

// Main function, responds to AWS API Gateway.
exports.handler = async function (event, context) {
    var promise = new Promise(function(resolve, reject) {
        var response = {
            httpStatus : 200,
            message : "Success"
        };
        resolve(JSON.stringify(response));
    });
    return promise;
};

我确保部署了 API 和 Lambda。 如何获得非 202 状态(即让 API 网关等待异步 lambda)?

【问题讨论】:

  • 那么,你想要哪一个?您是否想要同步结果主体 - 异步调用不会产生结果/主体,同步会。您不能拥有异步 lambda 并等待其响应,此时您不再拥有异步 lambda。来自文档:“在这种情况下,后端 Lambda 函数被异步调用,并且前端 REST API 方法不返回结果。”
  • @luk2302 我有以下(不正确的)心智模型:前端(网站)可以恢复其业务(而不是对用户无响应),但是当异步过程最终完成时,前端可以处理该响应。但相反,一旦它到达异步 lambda,似乎没有任何响应(除了 200)。所以我的问题是:如果 lambda 中的某些内容失败(例如,recaptcha 验证或向 SQS 添加数据),有没有办法通知网站/用户?我的网站是否应该将数据发布到同步 lambda(通过 API 网关)?
  • 对于 API,大多数时候您希望进行同步调用。也许 lambda 只在 dynamodb 中插入一行,返回其 id 并触发另一个 lambda 来完成繁重的工作,但这取决于您的决定。特别是您需要问自己,API 是否应该将操作建模为自己的实体,创建客户实体是否需要这么长时间和这么多工作并且在此期间应该可以取消,那么是时候在您的实际拥有 CustomerCreationRequest 资源了API。但是你仍然可能会有同步的 lambdas 调度,例如sqs 消息
  • @luk2302 我从同步 lambda 开始,但根据一些 AWS 文档切换(例如 docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html 列出“Node.js 中的示例 Lambda 应用程序”,而 API 网关是异步的:@ 987654323@)。我真的只在 lambda 中做两件事:检查 recaptcha 的有效性,然后添加到 SQS(供其他人处理)。我将切换回同步 - 谢谢。
  • 不,这不是异步 lambda。该代码仅使用特定于语言的 async 关键字,但这与部署异步 lambda 的基础设施完全无关。这两者具有相同的关联术语,(a)同步,但它们彼此无关。

标签: node.js amazon-web-services aws-lambda aws-api-gateway


【解决方案1】:

这是按预期工作的。 AWS docs on "Asynchronous invocation" 中的第二句话说:

当您异步调用函数时,您无需等待函数代码的响应。

如果您想要一个带有结果的响应,异步调用将不起作用。

【讨论】:

  • 补充:API 网关应该使用与 Lambda 的同步(例如 AWS_PROXY)集成,但 Lambda 内部发生的事情仍然可以是异步的。
  • @Sleavely 不,它“应该”肯定是错误的措辞 - 因为如果没有用于异步调用的用例,则该功能将不存在。并且 lambda 本身通常不能真正异步,您必须同步返回响应到网关请求,是的,您可以在两者之间做一些异步的事情,但是 lambda 必须同步回答,并且在它回答后完成处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-17
  • 1970-01-01
  • 2013-05-14
  • 2022-01-17
  • 2019-05-25
  • 2014-12-03
  • 1970-01-01
相关资源
最近更新 更多