Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous HTTP request in AWS Lambda

I am wanting to execute a http request inside of a lambda function, invoked by API Gateway. The problem is, the request takes a bit of time to complete (<20 seconds) and don't want the client waiting for a response. In my research on asynchronous requests, I learned that I can pass the X-Amz-Invocation-Type:Event header to make the request execute asynchronously, however this isn't working and the code still "waits" for the http request to complete.

Below is my lambda code:

'use strict';

const https = require('https');

exports.handler = function (event, context, callback) {
    let requestUrl;
    requestUrl = event.queryStringParameters.url;

    https.get(requestUrl, (res) => {
        console.log('statusCode:', res.statusCode);
        console.log('headers:', res.headers);

        res.on('data', (d) => {
            process.stdout.write(d);
        });
    }).on('error', (e) => {
        console.error(e);
    });

    let response = {
        "statusCode": 200,
        "body": JSON.stringify(event.queryStringParameters)
    };
    callback(null, response);
};

Any help would be appreciated.

like image 478
Bobby Bruce Avatar asked Jan 19 '18 19:01

Bobby Bruce


People also ask

Is AWS Lambda asynchronous or synchronous?

Lambda functions can be invoked either synchronously or asynchronously, depending upon the trigger. In synchronous invocations, the caller waits for the function to complete execution and the function can return a value.

Can Lambda make HTTP request?

Full request passthrough – Using the Lambda proxy ( AWS_PROXY ) integration type, a Lambda function can receive an entire HTTP request (instead of just the request body) and set the HTTP response (instead of just the response body).

What is asynchronous invocation in Lambda?

For asynchronous invocation, Lambda places the event in a queue and returns a success response without additional information. A separate process reads events from the queue and sends them to your function. To invoke a function asynchronously, set the invocation type parameter to Event .

Does API gateway invoke Lambda asynchronously?

You can invoke a Lambda function asynchronously via API Gateway only if the integration is non-proxy. By default, HTTP APIs are designed to support only proxy integrations for Lambda and HTTP endpoints so it is not possible to set the X-Amz-Invocation-Type header in the API Gateway integration config.


2 Answers

You can use two Lambda functions.

Lambda 1 is triggered by API Gateway then calls Lambda 2 asynchronously (InvocationType = Event) then returns a response to the user.

Lambda 2, once invoked, will trigger the HTTP request.

like image 166
Noel Llevares Avatar answered Oct 12 '22 12:10

Noel Llevares


Whatever you do, don't use two lambda functions.

You can't control how lambda is being called, async or sync. The caller of the lambda decides that. For APIGW, it has decided to call lambda sync.

The possible solutions are one of:

  • SQS
  • Step Functions (SF)
  • SNS

In your API, you call out to one of these services, get back a success, and then immediately return a 202 to your caller.

If you have a high volume of single or double action execution use SQS. If you have potentially long running with complex state logic use SF. If you for someone reason want to ignore my suggestions, use SNS.

Each of these can (and should) call back out to a lambda. In the case that you need to run more than 15 minutes, they can call back out to CodeBuild. Ignore the name of the service, it's just a lambda that supports up to 8 hour runs.


Now, why not use two lambdas (L1, L2)? The answer is simple. Once you respond that your async call was queued (SQS, SF, SNS), to your users (202). They'll expect that it works 100%. But what happens if that L2 lambda fails. It won't retry, it won't continue, and you may never know about it.

That L2 lambda's handler no longer exist, so you don't know the state any more. Further, you could try to add logging to L2 with wrapper try/catch but so many other types of failures could happen. Even if you have that, is CloudWatch down, will you get the log? Possible not, it just isn't a reliable strategy. Sure if you are doing something you don't care about, you can build this arch, but this isn't how real production solutions are built. You want a reliable process. You want to trust that the baton was successfully passed to another service which take care of completing the user's transaction. This is why you want to use one of the three services: SQS, SF, SNS.

like image 43
Warren Parad Avatar answered Oct 12 '22 14:10

Warren Parad