Serverless architectures make use of a FaaS (Function as a Service) like AWS Lambda. FaaS gives developers the ability to send their application code to the cloud provider and have it be run in an isolated way with all the details of the underlying Server abstracted away from them. These Functions must be invoked by a trigger, be that direct invocation from the AWS SDK, through HTTP via API Gateway, a DynamoDB Stream, Kinesis, Cognito, Alexa or S3…
From these examples of FaaS triggers, we can see that move to adopt Serverless is a move to a more Event-Driven paradigm.
A Serverless-First architecture has to treat Events as First-Class Citizens — it’s the only way to truly embrace the power of Cloud-Native.
There are many debates on how Lambda functions should be architected, ranging from the Monolithic approach with “one lambda to rule them all”, to a split by Services or a Microservice/MicroLambda approach.
From my experience, the finer the granularity of your functions the better the performance and adaptability of your architecture.
Microservices are hard. Managing API versioning, communications between teams, data duplication and many other aspects prove challenging.
So, in a “Micro-Lambda” approach, with extremely fine-grained Lambda functions: how exactly are we making our lives easier?
In fact, we’re going to have many more services interacting with each other and responding to CloudNative events, not just HTTP.
In 2019 AWS released a new Serverless service, Amazon EventBridge, formalising the flow of Events through architectures. It does this by providing Event Bus(es) for Events to flow through, along with tooling for developers to interact with these Events.
EventBridge has been viewed by the Serverless community as the biggest announcement since AWS Lambda. This is because the Serverless community is moving to Event-Driven architectures, and EventBridge was the missing piece to the Event-Driven Serverless puzzle.
Event: “A significant change in state” — K. Mani Chandy
EventBridge helps us move away from synchronous requests passed between a tangle of Lambda functions that result in a “Lambda Pinball” anti-pattern with requests bounced between Lambdas, S3 Buckets, SQS, SNS and so on. Instead, we think in terms of unidirectional Events.
How is this different from CloudWatch Events?
It’s the same underlying technology AWS uses to dispatch events generated by the AWS Services you already use. To quote AWS:
“CloudWatch Events and EventBridge are the same underlying service and API, but EventBridge provides more features.” — AWS
CloudWatch Events enabled your architecture to respond to events generated by the AWS Services you use, and although there is functionality to generate your own events and use cron and rate triggers — this was not the primary function of CloudWatch Events.
That being said, before EventBridge formalised the approach, some Serverless Architectures started to make use of CloudWatch Events to have a hacky EventBus concept.
Default vs Custom Event Bus
Every AWS Account always has at least 1 EventBus, the default EventBus, which contains the classic CloudWatch Events for changes in AWS Services. EventBridge also allows your architecture to create its own EventBus(es), and this is where the true power of EventBrige comes into play.
Via the AWS Console, or via IaC solutions like the Serverless Framework, you can create EventBuses for your architectural needs and have Events that enter these Buses trigger specific Lambda functions. This is a game-changer in the simplification communication between Microservices and helps us move towards the Event-Driven paradigm.
EventBridge Schema Registry
“The Amazon EventBridge schema registry stores event structure — or schema — in a shared central location and maps those schemas to code for Java, Python, and Typescript so it’s easy to use events as objects in your code.” — AWS
When Microservices are managed by different teams, communication between those teams can be difficult. For instance, if you have a Payment team processing payments from customers and a Marketing team who want to trigger a follow-up survey 2 weeks after purchase, those two teams will need to coordinate to ensure the Survey email is triggered.
Yet, what if we’re Event-Driven and it’s just a case of both teams listening for a “PAYMENT SUCCESS” Event — well with an EventBridge based architecture we are!
Now, what if the marketing team could know exactly which event to listen to and the typed structure of the Event (first name, last name & email fields…) without even having to talk to the other team?
Or the developer even leaving their IDE?
Well, luckily AWS extended the functionality of EventBridge with the Amazon EventBridge Schema Registry. The Schema Registry not only allows you to create and manage Schemas for Events, it also automatically generates Schemas for Events flying through any EventBus by inferring their schema from the Event instances. These Schemas are in OpenAPI format but can also be downloaded as fully-typed code bindings for TypeScript, Java & Python.
How to start with EventBridge?
Well, the first step is a mindset shift to start thinking about your architecture in terms of Events, moving to being Event-Driven. Conducting an Event Storming workshop is a great way to generate a list of the key Events your system needs to process in business domain terms. These events can then help you to identify the microservice boundaries in your system.
From here it’s a case of creating a Custom Event Bus and filtering & routing the right Events to the right destinations.
Creating a Custom Event Bus is extremely simple in the latest version of the Serverless Framework:
By simply adding an EventBridge trigger on a function, the Serverless framework will automatically create this new custom EventBus (in this case “application-bridge”). Further to this, it will set a rule for the Lambda Function to be triggered on Events passing through this bus with the correct source attribute (in this case “custom.hello”).
We can check this works with a simple JS script
Side Note: Triggering Lambdas through EventBus is obviously different from triggering via HTTP. Developers can’t rely on CURL/Postman to trigger their functions easily during development. Therefore this is on the backlog for the sls-dev-tools project to be able to “Inject Events” quickly and repeatedly.
(See the progress on the GitHub Project board)
Myself, along with many in the Serverless community, view EventBridge as the biggest thing for Serverless architectures since Lambda.
Serverless architectures work best when they are structured in an Event-Driven way, and EventBridge was the missing puzzle piece to do this well.
EventBridge simplifies communication between services & teams, reduces tight-coupling and helps us avoid the Distributed Monolith.
It’s time to treat Events as First-Class Citizens, and EventBridge is the tool to do this.
At Theodo we are now starting all our Serverless projects with EventBridge by default!