Event-driven architecture (EDA) is a software architecture model for application design. It promotes the publication, delivery, and consumption of specific events. For example, an “event” could be a user purchasing a new t-shirt through an online store. The purchase will trigger an event stream which feeds information to different components of the application such as inventory, shipping, and communication services. Event-driven architectures set successful cloud-native organizations ahead of their competition. In cases where loosely coupled microservices will accelerate the design and build processes, EDA is the way to go.
Event-Driven or Request-Driven Architecture?
Event-driven architecture differs from a more traditional request-driven model.
In a request-driven model, one event triggers actions in other systems directly. For example, placing an order for a new t-shirt (also known as an orchestrator event) will trigger the inventory database, shipping service, and email services (dependent systems) to function as intended. In this model there is a clear control of the flow. By looking at the code of the orchestrator, we can determine the sequence of the actions. These microservices are tightly coupled. This can introduce complex failure modes that are impossible to recover gracefully, as one domino topples into the others bringing the whole system down.
In an event-driven model, the key differentiator is that each service performs its function asynchronously, resulting in a loosely coupled system. Rather than wait for an orchestrator event to tell a dependent event to do its job, an orchestrator will publish an event stream. The orchestrator and the dependent services of the events do not necessarily know about each other because they only communicate with the event stream, rather than each other as in a request-driven model. As a result, services can be deployed, scaled and maintained independently. This is a key benefit of building loosely coupled microservices. It is also much easier to add, remove, or modify services in an event-driven model. This architecture allows developers to alter orchestrator events or dependent services without touching other parts of the application.
How an Event-Driven Architecture Functions
Following Cloud-Native Microservice architecture principles, EDA divides a big problem (e.g., shipping a large retail order to a customer) into smaller separations of concern, both horizontally and vertically.
Horizontal separation looks like individual events. For example: logging into a web app, creating a new user profile, updating a profile, saving a new order, searching for items that you want to purchase, and adding items to a shopping cart.
Vertical separation refers to the different components of an entire functional web app. For example: The user interface, the API integration, and the data storage.
These components are loosely coupled so that changes in one will not affect the operation of the others. Using an event service bus like Kafka, events are published using a publish/subscribe model that allows updates to be made asynchronously. The service bus communicates the update to other services to keep databases consistent, which allows us to use different databases for different functions without compromising data integrity. It also enables near real-time updates and easier scalability, which is a must-have in the software development lifecycle. Once all the pieces are functional, we use Kubernetes to orchestrate them.
Why Event-Driven Architecture Accelerates the Development Process
In an event-driven architecture, individual components of a web application can be built, modified, or even deleted without affecting the function of other components. Data consistency is not compromised in an event-driven development process, which is a primary concern with any microservice architecture.
Using an event-driven model allows you to scale your team and move through a project more efficiently. Smaller components can be designed and built concurrently, rather than waiting for orchestrator components to be functional before dependent components can be completed.
Based on the advantages of an EDA, request-driven models are considered a highly undesirable anti-pattern. Event-driven architecture is not an every-use-case hero; Some solutions are small enough that they don’t require division into smaller pieces. However, any problem that is large enough to be divided into smaller pieces should leverage an event-driven architecture. If there is an opportunity to implement event-driven microservice, EDA will provide a strong foundation for building loosely coupled microservices (and, likely, a quicker production timeline).