📝 en ~ 6 min
Event-Driven Architectures
Share this post
In this article, I will explore some trade-offs and the case for the use of event-driven architectures in modern applications. While I will focus on the products and services from AWS, we could use this architecture in any Cloud or on-premises.
In September 2021, Corey Quinn, Chief Cloud Economist at The Duckbill Group published The Key to Unlock the AWS Billing Puzzle is Architecture and I identified myself a lot with some of his remarks. One, sometimes downplayed is the notion cost is architecture.
For example, if you didn’t use SQS when building your application because it couldn’t handle your throughput needs or it was too expensive, that changed a couple of weeks ago. SQS is to the point where it’s now effectively unlimited throughput at a cost that’s just 3.6% of what it was at launch.
And the 3.6% was because of a typo by Zack Kanter. In fact, the price drop is 99.4% from 2006. Which makes it cost only 0.6% of what was. You will pay less than 1% it was years ago!
Loosing our couplings
Section titled %5Bobject%20Undefined%5DThere’s general advice that is very well known in modern software architecture, at leat in the web or distribute space that advocates for loose coupling. And sure, is a noble goal but there are several kinds of coupling such as Temporal coupling when we deal wit time-based dependencies such as collaborating system components, sequential operations or operations that needs another to complete such a request or another operation. We have Spatial coupling such as not having to know where your collaborating applications are in the network and providing fail-over mechanisms such as Load Balancers, pub/subs, and other. And of course, this comes a lot even more on the serverless space than any other in the Cloud: Platform coupling. Have proprietary protocols and components from a vendor or platform.
But as pointed, coupling is a function of multiple dimensions, not just binary options like “tight” or “loose”. We are always. Always working with trade-offs.
“The event-driven architecture style is a popular distributed asynchronous architecture style used to produce highly scalable and high-performance applications. It is also highly adaptable and can be used for small applications and as well as large, complex ones. Event-driven architecture is made up of decoupled event processing components that asynchronously receive and process events. It can be used as a standalone architecture style or embedded within other architecture styles (such as an event-driven microservices architecture).”
Following the inspiration from Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans and later, Domain-Driven Design Distilled and Implementing Domain-Driven Design by Vaughn Vernon one of way to model and work with software involves deal with bounded contexts we can map and create services, applications and systems to better tackle our problems. And to integrate all of this, one pattern is Domain Events.
Event becomes the primary mechanism for sharing information across bounded context integrations about change in state. Domains events are immutable, self-describing. Events give the data they carry meaning by supplying business context. Not data transfer objects or change data captures. These are state / state change representations that are not reflective of a system’s behaviour.
An event is a quanta, a unit that describes something in the system. Could be a simple JSON as that:
{
"eventId": 61452,
"event": "OrderPlaced",
"createdAt": "2021-10-07"
}
For example, with this event, different domains could decide to act or not in the event. Maybe we have an Inventory domain, a Package domain, a service that will email the user about the order and each one will handle the event as seem fit, and we could add and apply as many services and applications needed. We will publish all these events to “Bus”, which in the AWS is via Amazon EventBridge. As a CDK enthusiast, even to create your Infrastructure as Code in a couple of lines of TypeScript.
import * as cdk from '@aws-cdk/core';
const stack = new stack();
const bus = new EventBus(stack, 'bus', {
eventBusName: 'MyCustomEventBus'
});
bus.archive('MyArchive', {
archiveName: 'MyCustomEventBusArchive',
description: 'MyCustomerEventBus Archive',
eventPattern: {
account: [stack.account],
},
retention: cdk.Duration.days(365),
});
With the code above you could provision a custom event bus and create an 365-day archive of all events, that if needed, could be used to auditing or event replay. And even in my example, let’s say the user wants to cancel the order, we will not delete the previous event or even modify it — Events must be immutable. Different domains will need to process the new events in order to undo actions or make an analysis about how and why and so on.
{
"eventId": 61456,
"event": "OrderCancelled",
"createdAt": "2021-10-07"
}
Maybe another email will be sent, to confirm the cancel, Inventory Package will have to adjust their line of work and so on. And now maybe a CRM system you be fed to understand why the customer canceled after the conversion.
Coupling will always exist. But we can orchestrate with such services and create highly responsive, available and robust architectures. And you can combine EventBridge with Lambda, SNS, SQS, Step Functions and soon you are dealing with systems that can scale up and down easily and if done correctly, try to optimize a lot your costs because some services and applications we have today sitting at some servers 24/7 sometimes just need to be active when a specific event happens.
Right now I’m in the middle of an event-driven creation and I really like the mental model and the developer experience as the organization experience and soon we used the “Ubiquitous Language” from DDD. And for this set of tools, none other Cloud seems so fit and solid as AWS does.
Books to read
Section titled %5Bobject%20Undefined%5D-
Building Event-Driven Microservices: Leveraging Organizational Data at Scale by Adam Bellemare. Brings much value with both architectural and application patterns to event-driven architecture.
-
Architecture Patterns with Python: Enabling Test-Driven Development, Domain-Driven Design, and Event-Driven Microservices by Harry Percival and Bob Gregory. Python is not my primary language at work or even my preference, but I get so much from this book. Because is aiming at patterns if you do not work with Python don’t let the title fool you. There’s a lot from here in this book!
Heroes to follow
Section titled %5Bobject%20Undefined%5DYeah, they are actually heroes.
Ben Ellerby
Section titled %5Bobject%20Undefined%5D@EllerbyBen For me one of his post, helped me a lot in my work and opened so many possibilities: EventBridge Storming — How to build state-of-the-art Event-Driven Serverless Architectures. Blogs a lot about the concept of Serverless Transformation, a term I adopted too.
Sheen Brisals
Section titled %5Bobject%20Undefined%5D@sheenbrisals Blog often at Medium. Last post was How To Build Better Orchestrations With AWS Step Functions, Task Tokens, And Amazon EventBridge!