Icecream Flavour Picker using AWS Event Bridge
All you need to know about Event Bridge
In a distributed microservice architecture, we have many services, each doing one thing and each service interacts with other services. Initially, it looks like, each service is independent and we can deploy the changes faster. But as the application starts to grow, it tends to have a lot of interactions between services making the whole application tightly coupled.
In this blog, we will see what event bridge is and how it overcomes some of the shortcomings of microservice architectures.
A Tale of Microservice
A client makes a request to the order service, which then, in turn, sends a request to the delivery service. The delivery service returns 201 as a successful response to the order service and then the order service sends a response to the client. We all start from here and it looks like each service is decoupled from one another.
What happens when we add more services that integrate them with order service. Now as you see, the order service will have more responsibilities.
Order service will have to coordinate with each of the services. If there are any retry scenarios, the order service has to handle them. When one of the services has updated, the order service needs to update the same, so now, other services are waiting for the update to complete. What if we add a new service and order service is not aware of this new service? How about reverting the transactions? What about if one of the services is not available. So, now, we are in a complex situation. Microservice does not look like our friend.
Event Bridge
Amazon EventBridge is a serverless event bus service that you can use to connect your applications with data from a variety of sources. Events are central to EventBridge and the events are observable. Previously in a microservice architecture, we had an API, which would instruct each service on what action to take. But with events being observable, now, we just notify that some changes have happened to the event bus. Other consumers can listen to the event bus and take the action based on their use case.
As we see, when an order has been placed, the event is triggered on the event bridge. Other consumers like inventory service check the inventory and the delivery service checks the delivery. We can also have other consumers subscribed to the same event bridge and are not interested in the event, so they won't take any action. So, tight coupling which we saw in a microservice architecture is minimized.
Event bridge also supports integration with many SAAS-based applications and third-party applications. It also supports sending events to other AWS services like Lambda functions, step functions.
key benefits of Event Bridge
- Decoupling of applications
- Simplified event routing
- Improved availability
- Third-party integrations
Terminology used in Event Bridge
Events - An event indicates a change. This can be a change in AWS services, a third-party service, or one of our own custom applications.
Event buses - An event bus receives events. When you create a rule, you associate it with a specific event bus, and the rule is matched only to events received by that event bus. By default, the AWS account has a default event bus, which receives events from AWS services. We can create custom event buses to receive events. You can also create partner event buses to receive events from third-party applications.
Rules - A rule matches incoming events and routes them to specific targets for further processing. A single rule can route to multiple targets. Processing of Rules is not in any order, they can even process parallelly. A rule can also filter or enhance the JSON sent to the target service.
Targets - A target is the one that does the processing of events. Targets can be Lambda functions, Step Function state machines, or any built-in target. A target receives events in JSON format.
Icecream Flavor Picker: An Example
Let us see how we can create an Event Bus, define the Rules and the targets using the Icecream Flavor Picker Example.
The step function is used to trigger the eventbridge. EventBridge defines the rules, which will execute a specific lambda function. If the input to the step function is banana, the eventbridge banana rule executes, which in turn, triggers the banana lambda function. If the input to the step function is almond, the eventbridge almond rule executes, which in turn, triggers the almond lambda function.
Create a Step Function
- Create a state machine with the name IcecreamFlavourStateMachine.
- Define the step function as shown below.
Depending upon the type of flavor selected, it puts the events to a specific event Rule.{ "Comment": "A Ice Cream Flavor Chooser", "StartAt": "Create IceCream flavor", "States": { "Create IceCream flavor": { "Type": "Pass", "Next": "Flavor Choose" }, "Flavor Choose": { "Type": "Choice", "Choices": [ { "Variable": "$.icecreamFlavor.nut", "StringEquals": "almond", "Next": "Almond Flavor" }, { "Variable": "$.icecreamFlavor.nut", "StringEquals": "banana", "Next": "Banana Flavor" } ], "Default": "DefaultState" }, "Almond Flavor": { "Type": "Task", "Resource": "arn:aws:states:::events:putEvents", "Parameters": { "Entries": [ { "Detail.$": "$.icecreamFlavor", "DetailType": "almond_flavor", "EventBusName": "Ice_cream_flavour", "Source": "IcecreamFlavor" } ] }, "End": true }, "Banana Flavor": { "Type": "Task", "Resource": "arn:aws:states:::events:putEvents", "Parameters": { "Entries": [ { "Detail.$": "$.icecreamFlavor", "DetailType": "banana_flavor", "EventBusName": "Ice_cream_flavour", "Source": "IcecreamFlavor" } ] }, "End": true }, "DefaultState": { "Type": "Fail", "Cause": "No Matches!" } } }
Create an EventBus and Event Rules
Event buses receive events from a variety of sources and match them to rules in your account.
- Create an event bus with the name Ice_cream_flavour
- Create a Rule with the name Almond_Rule
- Select the custom pattern as shown below
{ "source": ["IcecreamFlavor"], "detail-type": ["almond_flavor"] }
- Select the Target Lambda Function Almond_Icecream which we will create later.
- Create a Rule with the name Banana_Rule
- Select the custom pattern as shown below
{ "source": ["IcecreamFlavor"], "detail-type": ["banana_flavor"] }
- Select the Target Lambda Function Banana_Icecream which we will create later.
Create lambda functions
- Create a lambda function with the name Almond_Icecream and Banana_Icecream
- Change the code in index.js as below.
exports.handler = async (event) => { console.log(event); var nutType = event.detail.nut; console.log("The type of Flavor is: ", nutType); return nutType; };
Test the application
- Let us send the following almond JSON to IcecreamFlavourStateMachine step function
When we start the execution, we see that it triggers the almond event bridge rule as can be seen below.{ "icecreamFlavor": { "nut": "almond" } }
We also see the event Id ae9a19c8-72d7-e5e9-1fa0-87c3f4666faa
, using which we can verify that Almond_Icecream lambda function is called.
- Let us send the following banana JSON to IcecreamFlavourStateMachine step function
When we start the execution, we see that it triggers the banana event bridge rule as can be seen below.{ "icecreamFlavor": { "nut": "banana" } }
We also see the event Id fcbfbe74-8a05-00fe-6aa5-01793b4c2c1f
, using which we can verify that Banana_Icecream lambda function is called.
Conclusion
In this blog post, we looked at what event bridge is and how to create rules and apply a pattern to the rules. We have seen the example application of Icecream Flavour Picker using step functions, event bridge, and lambda functions. To know more about the event bridge, step functions and lambda functions head over to official documentation docs.aws.amazon.com.