Deep dive: 3 ways to invoke AWS Lambda Function 
Tags: serverless, awslambda, javascript
Published: 2020-01-02 04:38:52

---
title: Deep dive: 3 ways to invoke AWS Lambda Function 
published: true
description: AWS Lambdas functions are everywhere. We are using it for various use cases. Here are 3 different ways we can invoke AWS Lambda function.
tags: serverless, aws lambda, javascript
---

![AWS Diagram](https://thepracticaldev.s3.amazonaws.com/i/4rvkh4i3c1rq79td0gqk.png)

`AWS Lambda` functions are everywhere. We are using it for various use cases. Sometimes we want to invoke Lambda functions over `HTTP` and other times `trigger` a function based on some external events. It is extremely useful to understand the different ways we can invoke Lambda functions. Here are 3 different ways we can invoke AWS Lambda function:

## Synchronous Invokes

This is the simplest lambda invocation model. When we perform a Lambda invoke an API call, we wait for the function to process the event and return a response or times out. The response includes the function response and additional data.

To perform synchronous invocation we can use the CLI or any of the supported SDKs.

Example of synchronous invoke using the CLI:

```bash
aws lambda invoke —function-name MyLambdaFunction —invocation-type RequestResponse —payload  '{ "key": "value" }'
```

Example of synchronous invoke using the Node.js SDK:

```javascript
const AWS = require("aws-sdk");

const lambda = new AWS.Lambda();

const params = {
  FunctionName: "MyLambdaFunction",
  InvocationType: "RequestResponse",
  Payload: JSON.stringify({ key: "value" })
};

await lambda.invoke(params).promise();
```

> When we specify the `Invocation-type` flag or `InvocationType` parameter value as `RequestResponse` it instructs AWS to execute our function and wait for the function to complete. One of the drawbacks of synchronous invoke is we are responsible for checking the response and determining whether it is an error and we should retry the invoke.

There are many AWS services that can trigger lambda function synchronously. Here are some of them:

- ELB (Application Load Balancer)
- Cognito
- Lex
- Alexa
- API Gateway
- CloudFront (Lambda@Edge)
- Kinesis Data Firehose

## Asynchronous Invokes

When we invoke a function asynchronously, Lambda sends the event to a queue and returns a success response without additional information. A separate process reads events from the queue and runs our function. To invoke a function asynchronously, we have to set the invocation type parameter to Event.

Example of an asynchronous invokes using the CLI:

```bash
aws lambda invoke —function-name MyLambdaFunction —invocation-type Event —payload  '{ "key": "value" }'
```

Example of an asynchronous invokes using the Node.js SDK:

```javascript
const AWS = require("aws-sdk");

const lambda = new AWS.Lambda();

const params = {
  FunctionName: "MyLambdaFunction",
  InvokeArgs: JSON.stringify({
    Records: [
      {
        eventVersion: "2.0",
        eventSource: "aws:s3",
        awsRegion: "us-west-2",
        eventTime: "1970-01-01T00:00:00.000Z",
        eventName: "ObjectCreated:Put",
        userIdentity: {
          principalId: "AIDAJDPLRKLG7UEXAMPLE"
        },
        requestParameters: {
          sourceIPAddress: "127.0.0.1"
        },
        responseElements: {
          "x-amz-request-id": "C3D13FE58DE4C810",
          "x-amz-id-2":
            "FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD"
        },
        s3: {
          s3SchemaVersion: "1.0",
          configurationId: "testConfigRule",
          bucket: {
            name: "sourcebucket",
            ownerIdentity: {
              principalId: "A3NL1KOZZKExample"
            },
            arn: "arn:aws:s3:::sourcebucket"
          },
          object: {
            key: "HappyFace.jpg",
            size: 1024,
            eTag: "d41d8cd98f00b204e9800998ecf8427e",
            versionId: "096fKKXTRTtl3on89fVO.nfljtsv6qko"
          }
        }
      }
    ]
  })
};

await lambda.invokeAsync(params).promise();
```

`You can use the above code snippet to write integration tests for your lambda function that gets trigger based on the s3 event.`

> When we specify the `Invocation-type` flag or `InvocationType` parameter value as `Event` if the function failed AWS will automatically retry the invoke twice. 

Here is a list of services that invoke Lambda functions asynchronously:

- S3
- SNS
- SES
- CloudFormation
- CloudWatch Logs
- CloudWatch Events
- CodeCommit

## Pool Based Invokes

Pool-Based invocation model allows us to integrate with AWS Stream and Queue based services. Lambda will poll records from services (`Kinesis, SQS, DynamoDB Streams`) and invoke our functions. AWS Lambda Event Source Mapping manages the poller and performs Synchronous invokes of our function.

Here is an example mapping of a function (`MyLambdaFunction`) to a Kinesis stream (`arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream`) with a batch size of 500:

```bash
$ aws lambda create-event-source-mapping --function-name MyLambdaFunction \
--batch-size 500 --starting-position AT_TIMESTAMP --starting-position-timestamp 1541139109 \
--event-source-arn arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream
{
    "UUID": "2b733gdc-8ac3-cdf5-af3a-1827b3b11284",
    "BatchSize": 500,
    "MaximumBatchingWindowInSeconds": 0,
    "ParallelizationFactor": 1,
    "EventSourceArn": "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream",
    "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:MyLambdaFunction",
    "LastModified": 1541139209.351,
    "LastProcessingResult": "No records processed",
    "State": "Creating",
    "StateTransitionReason": "User action",
    "DestinationConfig": {},
    "MaximumRecordAgeInSeconds": 604800,
    "BisectBatchOnFunctionError": false,
    "MaximumRetryAttempts": 10000
}
```

Here is an example lambda function that receives a Kinesis event input and processes the messages:

```javascript
exports.handler = async event => {
    event.Records.forEach(record => {
        // Kinesis data is base64 encoded so decode here
        const payload = Buffer.from(record.kinesis.data, 'base64').toString('ascii');
        console.log('Decoded payload:', payload);
    });
};

```

### Retry behavior of different invocation model

| Invocation Model | Retry Behavior                 |
|------------------|--------------------------------|
| Synchronous      | None                           |
| Asynchronous     | Twice                          |
| Pool Based       | Retry based on data expiration |


Now you know 3 different ways to invoke Lambda functions. If you have questions or suggestions please feel free to let me know in the comments.