Skip to content

Commit 523d21f

Browse files
authored
add sample for lambda event filtering with dynamodb and sqs (#149)
* add sample for lambda event filtering with dynamodb and sqs * add more context in docs
1 parent 4b5ab00 commit 523d21f

File tree

4 files changed

+191
-0
lines changed

4 files changed

+191
-0
lines changed

lambda-event-filtering/README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# AWS Lambda event filtering with DynamoDB and SQS
2+
3+
Simple demo application illustrating AWS Lambda event source filtering with DynamoDB and SQS. For this demo, we will use AWS Serverless Application Model (SAM), and a thin LocalStack wrapper `samlocal` to create our infrastructure through SAM on LocalStack.
4+
5+
## Prerequisites
6+
7+
* LocalStack
8+
* Docker
9+
* `make`
10+
* [`awslocal`](https://github.com/localstack/awscli-local)
11+
* [`samlocal`](https://github.com/localstack/aws-sam-cli-local)
12+
* NodeJS 14.x
13+
* [`ulid`](https://www.npmjs.com/package/ulid)
14+
15+
## Installing
16+
17+
Setup [Serverless Application Model (SAM)](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) and [AWS SAM CLI Local](https://github.com/localstack/aws-sam-cli-local) on your local machine. We also recommend using NodeJS 14.x alongside a [Node Version Manager](https://github.com/nvm-sh/nvm) to manage your NodeJS versions.
18+
19+
20+
Start LocalStack via:
21+
22+
```sh
23+
localstack start -d
24+
```
25+
26+
## Deploy the application
27+
28+
Let us first install the local dependencies:
29+
30+
```sh
31+
npm install --save ulid
32+
```
33+
34+
To setup the infrastructure on LocalStack, run:
35+
36+
```sh
37+
samlocal deploy -g
38+
```
39+
40+
You will be prompted to enter a name for the stack. Use the default options for the prompts and fill `Y` (`Yes`) for the confirmation prompt. The stack will be created and the output will be printed to the console.
41+
42+
If you have made any changes to the application, you can update the stack by running:
43+
44+
```sh
45+
samlocal deploy
46+
```
47+
48+
After deploying you can send a SQS message to the queue and see the Lambda function being triggered:
49+
50+
```sh
51+
awslocal sqs send-message --queue-url http://localhost:4566/000000000000/MyQueue --message-body "{ "data" : "A" }" --delay-seconds 10
52+
```
53+
54+
You will see a JSON output similar to the following:
55+
56+
```json
57+
{
58+
"MD5OfMessageBody": "64dfee8647a8264b25b01b7f22d72d3a",
59+
"MessageId": "22fbddd2-5add-4a03-a850-152780d786c1"
60+
}
61+
```
62+
63+
In the `template.yaml` we have defined the DynamoDB table and the Stream function with a filtering criteria. We instruct the Stream function to trigger the Lambda function only when the filtering criteria is satisfied.
64+
65+
Using the SQS, we send a message body to the DynamoDB stream to match the specific filtering criteria. After the message is sent, we can see the Lambda function being triggered and you can check the logs to verify it.
66+
67+
## Destroy the application
68+
69+
To destroy the infrastructure on LocalStack, run:
70+
71+
```sh
72+
samlocal delete
73+
```

lambda-event-filtering/handler.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
'use strict';
2+
3+
const AWS = require('aws-sdk');
4+
const ULID = require('ulid');
5+
const dynamo = new AWS.DynamoDB.DocumentClient();
6+
7+
const TABLE_NAME = process.env.TABLE_NAME
8+
9+
exports.save = async (event) => {
10+
console.log(event);
11+
12+
const object = event.body;
13+
14+
const item = {
15+
id: ULID.ulid(),
16+
object,
17+
date: Date.now()
18+
}
19+
20+
console.log(item);
21+
22+
const savedItem = await saveItem(item);
23+
24+
return {
25+
statusCode: 200,
26+
body: JSON.stringify(savedItem),
27+
}
28+
}
29+
30+
exports.processDynamo = async (event) => {
31+
console.log(event);
32+
}
33+
34+
exports.processASQS = async(event) => {
35+
console.log('Process A');
36+
console.log(event);
37+
}
38+
39+
async function saveItem(item) {
40+
const params = {
41+
TableName: TABLE_NAME,
42+
Item: item
43+
};
44+
45+
console.log(params)
46+
47+
return dynamo.put(params).promise().then(() => {
48+
return item;
49+
});
50+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "lambda-event-filtering",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "handler.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"dependencies": {
10+
"ulid": "^2.3.0"
11+
}
12+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
AWSTemplateFormatVersion: '2010-09-09'
2+
Transform: AWS::Serverless-2016-10-31
3+
4+
Resources:
5+
6+
ProcessDynamoDBStreamFunction:
7+
Type: AWS::Serverless::Function
8+
Properties:
9+
Handler: handler.processDynamo
10+
CodeUri: .
11+
Runtime: nodejs14.x
12+
Events:
13+
Stream:
14+
Type: DynamoDB
15+
Properties:
16+
Stream: !GetAtt DynamoDBTable.StreamArn
17+
BatchSize: 1
18+
StartingPosition: TRIM_HORIZON
19+
FilterCriteria:
20+
Filters:
21+
- Pattern: "{ \"eventName\" : [\"INSERT\"] }"
22+
23+
ProcessASQSFunction:
24+
Type: AWS::Serverless::Function
25+
Properties:
26+
Handler: handler.processASQS
27+
CodeUri: .
28+
Runtime: nodejs14.x
29+
Events:
30+
MySQSEvent:
31+
Type: SQS
32+
Properties:
33+
Queue: !GetAtt MyQueue.Arn
34+
BatchSize: 1
35+
MaximumBatchingWindowInSeconds: 0
36+
FilterCriteria:
37+
Filters:
38+
- Pattern: "{\"body\": { \"data\" : [\"A\"] }}"
39+
40+
DynamoDBTable:
41+
Type: AWS::DynamoDB::Table
42+
Properties:
43+
AttributeDefinitions:
44+
- AttributeName: id
45+
AttributeType: S
46+
KeySchema:
47+
- AttributeName: id
48+
KeyType: HASH
49+
BillingMode: PAY_PER_REQUEST
50+
StreamSpecification:
51+
StreamViewType: NEW_IMAGE
52+
53+
MyQueue:
54+
Type: AWS::SQS::Queue
55+
Properties:
56+
QueueName: MyQueue

0 commit comments

Comments
 (0)