Day 4 of AWS re:Invent was all-out on serverless. The keynote from Werner Vogels, which he did in a half-life t-shirt that looked remarkably like the AWS Lambda logo, did start promising. He focussed on all the areas that I have tried advocating in the past. Try to stay async and event-driven! This allows you to create evolvable architectures. This was summarized in an iconic slide - Evolve or Die!
In this post I will discuss what that means and provide an architectural pattern for using EventBridge that allows you to evolve - not die.
Event-driven architectures are for everyone!
The first thing I want to make clear on Event-driven architectures is this: Almost every architecture can utilize it! Every application has processes that do not need a synchronous response. For example, an endpoint for adding an item to a shopping cart only needs to be pushed out, without direct feedback required to the customer. Let's see how to implement this in your applications!
Simple asynchronous, event-driven architecture patterns
A very useful pattern to utilize is Amazon EventBridge integration with AWS API Gateway. Let's consider the use-case of adding an item to a shopping cart. The API simply responds a static 'message received' and EventBridge then sends the payload data to one or more services for processing. This is shown in the diagram below.
You can set up EventBridge Integration with Api Gateway by creating an 'Integration' for a route, like shown below. Make sure the role of your API has permissions to perform the events:PutEvents
action!
Evolving your consumers
Besides running a simple lambda as a response to an event, you can set up more complex consumers. For example, if you want to send an email reminding the customer that an item is in their shopping cart, you can set up a pattern like the following using the new EventBridge Scheduler feature.
You can set up an extra Lambda that creates a scheduled event which for example runs one day after a product has been added to the shopping cart. An email service can be set up to trigger on this event. The SQS queue makes sure failures are able to be retried. You can do this without touching the original addToCart
flow! How's that for evolvability!
You can use boto3
to create such a scheduled reminder, as shown below. Make sure you have the latest version of boto3
installed.
import boto3
client = boto3.client('scheduler')
client.create_schedule(
ClientToken='my-token',
Description='Reminder in 1 day',
FlexibleTimeWindow={
'Mode': 'OFF'
},
GroupName='default',
Name='remindIn1Day',
ScheduleExpression='at(<your-desired-time>)', # formatted YYYY-MM-DDTHH:MM:SS
State='ENABLED',
Target={
'Arn': <event-bus-arn>,
'EventBridgeParameters': {
'DetailType': 'item X added to Cart',
'Source': 'putToCartService'
},
'Input': '{"scheduled_event": "true", "user": "my-user", "product": "my_product"}',
'RoleArn': <scheduler-role-arn>,
}
)
Get started!
The best to way start with event-driven architectures is by getting to know the services. So get started building to see what services and patterns work best for you!