Amazon EventBridge helps you to simplify your architecture, it is a serverless event bus service, you can use it to connect your applications with data from a variety of sources
The main parts of this article:
- Amazon EventBridge (Main components)
- About Event Bus
- Example
1. About Amazon EventBridge
EventBridge allows you to build event-driven architectures, which are loosely coupled and distributed. It enables you to be faster in building and innovating
Some Keynotes:
- Decoupling- When using distributed architecture, EventBridge makes sure the application remains decoupled
- Simplified event routing - Ensure services remain simple, only listening to events they care about, and only being responsible for creating events
- Improved Availability - In synchronous APIs the availability of the entire system can be impacted from the failure of any single service. While in asynchronous infrastructure based on events allows more resilience, and with the right architecture design you can improve availability too
- Third party integration - you can ingest data seamlessly in near real time using events
EventBridge main parts:
- Event Buses - An event bus is a pipeline that receives events. Rules associated with the event bus evaluate events as they arrive. Each rule checks whether an event matches the ruleβs criteria
- Events - An event is a real-time change in a system, data, or environment. This change can be either in your application or in an AWS service or a SaaS partner service
- Rules - A rule matches incoming events and sends them to targets for processing. A single rule can send an event to multiple targets, which then run in parallel. Rules are based either on an event pattern or a schedule
- Targets - A target is a resource or endpoint that EventBridge sends an event when it matches the event pattern defined for a rule. The rule processes the event data and sends the pertinent information to the target
π Note: For more information and detailed documentation you can visit the official site through this link
2. What is Event Bus?
An event bus is a pipeline that receives events. Rules associated with the event bus evaluate events as they arrive. Each rule checks whether an event matches the rule's criteria. You associate a rule with a specific event bus, so the rule only applies to events received by that event bus
Event producer don't need any knowledge who is listening to the events and on the other hand services that consume events don't need to know about upstream changes
Event Bus provides an endpoint where the event producer can send events, the router manages directing and filtering those events to the appropriate downstream consumers, consumers can get the events reliably while the producers remain decoupled
3. Example
In this section we are going to build a scenario based example
Before starting in serverless.yml we need to add the permission, so that our lambda function is able to put the event into the EventBridge
- serverless.yml:
provider:
name: aws
runtime: nodejs14.x
stage: v1
region: eu-west-1
iamRoleStatements:
- Effect: "Allow"
Action:
- "events:PutEvents"
Resource: "*"
Every time the user calls addProduct (Ξ»)
API, the lambda will add the item inside MySQL database and it will trigger an EventBridge that will trigger another Lambda Function to store the logs inside DynamoDB logProduct (Ξ»)
on API call:
store in MySQL Database
if stored successfully:
putEvents [Source, DetailType, Detail]
when we receive the event:
trigger target lambda:
get the value from `event`
put the data in DynamoDB
Rules inside EventBridge use Event Pattern
that are JSON objects, through the console we are going to create a Rule inside Amazon EventBridge that has the following Event Pattern
{
"source": ["log.addProduct"]
}
And then we specify which lambda function will be triggered in the targets section
The addProduct
Lambda function: (provoked from API Gateway)
- Route (routes.yml):
addProduct:
handler: src/modules/Test/controller/test.addProduct
events:
- http:
method: post
path: product
cors: true
- Body (sent from postman):
{
"userId": "user-123",
"name": "My First Book",
"category": "Finance",
"price": 100
}
π Note: I am using
mysql-serverless
in order to be able to query MySQL Database
- To stablish connection with my database:
const mysql = require('serverless-mysql')({
config: {
host: process.env.MYSQL_HOST,
database: process.env.MYSQL_DATABASE,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
}
});
module.exports.mysql = mysql;
π Note: In order to create my
Products
table in my database, we are going to useMySQL Workbench
, and run this sql code below:
use products;
CREATE TABLE Products (
ID int Not NULL AUTO_INCREMENT,
UserID varchar(255),
Name varchar(255),
Category varchar(255),
Price varchar(255),
PRIMARY KEY (ID)
)
- The
addProduct
Lambda function code:
module.exports.addProduct = async (event) => {
try {
console.log('event =>', event);
const body = JSON.parse(event.body);
const {
userId,
name,
category,
price,
} = body;
const result = await mysql.query(`INSERT INTO Products (UserID, Name, Category, Price) VALUES (?, ?, ?, ?)`, [userId, name, category, price]);
console.log('result =>', result);
const putEventResult = await putEvent(body);
console.log('putEventResult =>', putEventResult);
return {
statusCode: 200,
body: JSON.stringify({message: 'This is EventBridge API'}, null, 2),
};
} catch (error) {
console.log(error);
}
};
const AWS = require('aws-sdk');
const eventBridge = new AWS.EventBridge();
module.exports.putEvent = (body) => {
var params = {
Entries: [
{
Detail: JSON.stringify(body),
DetailType: 'add-product',
Source: 'log.addProduct'
}
]
};
return eventBridge.putEvents(params).promise();
}
If we can notice Source
here is log.addProduct
the value that we created previously from the console (Event Pattern
)
The logProduct
Lambda function code: (triggered from EventBridge)
- Route:
logProduct:
handler: src/modules/Test/controller/test.logProduct
- Code:
module.exports.logProduct = async (event) => {
try {
console.log('event =>', event);
const {
detail,
} = event;
const addResult = await putLog(detail);
console.log('addResult =>', addResult);
} catch (error) {
console.log(error);
}
};
const dynamoose = require('dynamoose');
const { v4: uuidv4 } = require('uuid');
const { Log } = require('./log.schema');
dynamoose.aws.sdk.config.update({
accessKeyId: process.env.access_key_id,
secretAccessKey: process.env.secret_access_key,
region: process.env.region,
});
module.exports.putLog = async (body) => {
const {
insertedId,
userId: UserId,
name: Name,
} = body;
return await Log.create({
PK: `Log#${uuidv4()}`,
SK: `Product#Log`,
ProductId: insertedId,
UserId,
Name,
Action: 'NEW_PRODUCT',
});
}
- Dynamoose Log Schema:
π Note: Dynamoose is a modeling tool for Amazon DynamoDB
const dynamoose = require('dynamoose');
const string_required = {
type: String,
required: true,
};
const number_required = {
type: Number,
required: true,
};
const LogSchema = new dynamoose.Schema({
PK: string_required,
SK: string_required,
ProductId: number_required,
UserId: string_required,
Name: string_required,
Action: {
type: String,
required: true,
enum: ["NEW_PRODUCT"],
},
});
module.exports.Log = dynamoose.model('Log', LogSchema);
The event output inside the CloudWatch for the logProduct lambda function:
2022-07-11T21:03:56.946Z e8e89bb6-1341-4bb9-88c6-3840f5ca2298 INFO event => {
version: '0',
id: '87dafa0a-9e87-9502-a032-c6b02b48a37a',
'detail-type': 'add-product',
source: 'log.addProduct',
account: '260776636198',
time: '2022-07-11T21:03:56Z',
region: 'eu-west-1',
resources: [],
detail: {
userId: 'user-123',
name: 'My First Book',
category: 'Finance',
price: 100,
insertedId: 1
}
}
- Lambda Layers (Dependencies):
{
"dependencies": {
"aws-sdk": "^2.1185.0",
"dynamoose": "^2.8.6",
"serverless-mysql": "^1.5.4",
"uuid": "^8.3.2"
}
}
Result:
- Data stored in MySQL Database:
- Data stored in DynamoDB:
π Note: To keep this blog simple I am using some of the parameters in the example above, in order to go deeper with AWS-SDK for Amazon EventBridge you can visit this link
4. Conclusion
In this article I tried to showcase how powerful the Amazon EventBridge is, and in case you are building distributed architecture it will help you a lot in decoupling your components
For more articles like this and to stay up-to-date, you can connect me on LinkedIn
This article is part of "Messaging with Serverless" series that I've been writing for a while, if you are interested to read other Serverless offerings from AWS, feel free to visit the links below
Top comments (0)