Api Gateway:用于Lambda集成的AWS子域

时间:2016-12-04 00:04:11

标签: amazon-web-services aws-lambda aws-api-gateway

我尝试集成我的lambda函数,它必须运行异步,因为它需要太长时间,使用API​​网关。我相信我必须,而不是选择" Lambda"集成类型,选择" AWS服务"并指定Lambda。 (例如thisthis似乎暗示了这一点。)

但是,我收到消息"用于集成的AWS ARN必须包含路径或操作"当我尝试将AWS子域设置为我的Lambda函数的ARN时。如果我将子域设置为我的Lambda函数的名称,则在尝试部署时,我会得到"用于集成的AWS ARN包含无效路径"。

此类集成的适当AWS子域名是什么?

请注意,我也可以接受this post的建议并设置Kinesis流,但这对我的简单用例来说似乎过分了。如果这是解决问题的正确方法,请尽快尝试。

编辑:包含的屏幕截图

Screenshot of my AWS API Gateway Integration Request Page

编辑:请参阅下面的评论,以获得不完整的解决方案。

2 个答案:

答案 0 :(得分:3)

所以设置起来非常烦人,但这有两种方式:

  1. 设置常规Lambda集成,然后添加此处描述的InvocationType标头http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html。值应为“事件”。

    • 这很烦人,因为当您将Lambda函数作为Integration类型时,控制台不会允许您添加标题。您必须使用SDK或CLI,或使用Swagger,您可以轻松添加标题。
  2. 将整个内容设置为控制台中的AWS集成(这就是您在问题中所做的事情),这样您就可以在控制台中设置InvocationType标头

    • 将子域名留空
    • “使用路径覆盖”并将其设置为/2015-03-31/functions/<FunctionARN>/invocations,其中<FunctionARN>是lambda函数的完整ARN
    • HTTP方法是POST
    • 添加值为X-Amz-Invocation-Type
    • 的静态标头'Event'
  3. http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html

答案 1 :(得分:1)

我所做的另一种选择是仍然使用Lambda配置并使用两个lambda。第一个代码(下面的代码)在第二个代码中运行,并立即返回。但是,它的真正作用是发射第二个Lambda(您的主要Lambda)作为Event,该Lambda可以长期运行(最多15分钟)。我发现这更简单。


/**
 * Note: Step Functions, which are called out in many answers online, do NOT actually work in this case.  The reason
 * being that if you use Sequential or even Parallel steps they both require everything to complete before a response
 * is sent.  That means that this one will execute quickly but Step Functions will still wait on the other one to
 * complete, thus defeating the purpose.
 *
 * @param {Object} event The Event from Lambda
 */
exports.handler = async (event) => {
    let params = {
      FunctionName: "<YOUR FUNCTION NAME OR ARN>",
      InvocationType: "Event",  // <--- This is KEY as it tells Lambda to start execution but immediately return / not wait.
      Payload: JSON.stringify( event )
    };

    // we have to wait for it to at least be submitted. Otherwise Lambda runs too fast and will return before
    // the Lambda can be submitted to the backend queue for execution
    await new Promise((resolve, reject) => {
        Lambda.invoke(params, function(err, data) {
            if (err) {
                reject(err, err.stack);
            }
            else {
                resolve('Lambda invoked: '+data) ;
            }
        });
    });

    // Always return 200 not matter what
    return {
        statusCode : 200,
        body: "Event Handled"
    };

};