After spending the last three years building high-assurance event-driven systems in healthcare and recently diving deep into Domain-Driven Design (DDD), I want to bridge these two worlds by breaking down the core concepts of Event-Driven Architecture. If you are brand new to EDA, I invite you to use this blog post as a starting point. Let’s dive into the basics!
Event-Driven Architecture (EDA) is a paradigm that works with creating, detecting, and consuming events. In Microservice Architecture, services act either as producers of those events, consumers, or both. Business and domain needs dictate whether these architecture patterns should be selected.
There are a few reasons why you might choose an event-driven design for your system.
-
Asynchronous communication: You might be designing a system where you want to avoid long wait times for something to happen. Then you could allow one part of your system to proceed rather than waiting for a response.
For example, you are designing a library book reservation system with a high number of users. While it may seem unrealistic, let’s imagine hundreds of book reservations or reservation cancellations per second. You want to let the user know that the book has been reserved instead of making the user wait for a few seconds or longer until the reservation database is actually updated. If you choose Event-Driven Architecture (EDA), your service that interacts with the user in this scenario is not blocked and doesn’t need to wait for their book to be reserved. We trust that the architecture will handle the user’s request and eventually reserve their book.
Decoupled systems: If you are implementing EDA in a microservice architecture, you can clearly see how event producer and consumer services operate independently. The separate management of these services is crucial for their scalability and adaptability to changes in business requirements.
Business logic across multiple consumers: You might find that your business requirements ask you to ensure that when one type of event happens, multiple other services can pick the process up from there and decide independently how to respond to specific events.
Can EDA be used in monolithic applications?
Yes, it can. It means the same application/service will be responsible for producing and consuming the events. It depends on the business requirements. One thing that monolithic architecture does not offer is physical decoupling of services. In microservice architecture, the event producer and consumer services are truly independent of each other. If something fails in the consumer service, for example, the producer and event backbone systems stay healthy. Once the consumer service is repaired and running smoothly, it can pick up the events from the queue or an event stream (event backbone), ensuring data reliability.
What are producers, consumers, and the event backbone?
It’s very simple. A producer is a service that creates the event. A consumer is a service that receives the event and reacts to it. And the event backbone is a service that sits in between the two and stores those events, almost like a mailbox.
Let’s say I have to design a system that deals with a high number of book reservations. After conversations with the business team in order to understand the domain, I have identified one of the events - the user reserved a book. That means there should be a producer service that creates the event BookReserved. This event should hold information about which user reserved the book and what book that is. The producer service pushes the event to the event backbone system that holds many BookReserved events.
I also have a third service - consumer. My consumer service is set up in a way that is constantly listening to the event backbone system to see if there are any new events. Once it picks up the BookReserved event, the consumer reads information about the book and the user. Then the consumer calls certain functions that mark the reservation in the database, change the status of that specific book instance, and similar.
As you can see from the diagram above, I selected my producer and consumer services to be implemented in .NET. Of course, it could be any other framework that fits your business needs and the team’s skillset.
How does the event backbone work?
The event backbone is the core of EDA. It is a crucial infrastructure component that can be implemented as an event bus, event broker, event router, or event hub (you may have heard some of these names).
The event backbone is the medium through which events produced by one component (the producer) are communicated to other components (the consumers). It ensures that when an event occurs, relevant consumers are notified and can act upon it independently.
Functionality:
- Producers inform the event backbone about events of interest.
- The event backbone routes these events to the appropriate consumers based on their subscriptions.
Technologies:
Many technologies implement the event backbone mechanism. The choice of which one to pick depends on how you want the events to be processed. Should we treat the events as a temporary message to be delivered or a permanent record to be stored?
Thinking of the messages in terms of their life span really helped me understand the difference between various technology options.
| Event data purpose | Technology category | Event Backbone Tools |
|---|---|---|
| Temporary Message | Message Brokers | RabbitMQ, ActiveMQ, AWS SQS / Azure Service Bus, NATS, IBM MQ |
| Semi-Permanent | Event Streaming | Apache Kafka, Redpanda, Apache Pulsar, Azure Event Hubs / AWS Kinesis |
| Permanent record | Event Sourcing | EventStoreDB, Marten, Axon Server, Eventuate |
The specific code you write for your producers and consumers to integrate with the event backbone is traditionally tied to the backbone technology you choose. Using a tool's native SDK means your code must follow a specific protocol, whether it's RabbitMQ's exchanges or Kafka's partitions.
There exist backbone-agnostic libraries, like Wolverine in .NET. They act as an abstraction layer between the code and infrastructure. You would set the right configuration, and then write generic handlers while letting the Wolverine framework manage the underlying connection to the event backbone.
Summary
Event-Driven Architecture allows microservices to operate independently, reducing latency and preventing system-wide bottlenecks. However, the most critical takeaway isn't the tech stack. It's the alignment with your domain. Whether you choose a Message Broker for instant tasks or Event Streaming for a historical record, the decision must start with your business requirements. By understanding how your data needs to live and move, you can build a system that isn't just "event-driven," but purpose-driven.


Top comments (0)