Why Event-Based Systems? | Enterprise Node.js + TypeScript
There are several ways to design systems. When I first starting building applications, I would start out with the database. Eventually, I realized that the view dictates the data, so I moved to starting out with the UI. Then I realized that I was failing to represent a lot of important business rules, so I began to search for something else.
Eventually I found Domain-Driven Design and starting building applications by first understanding the domain, then working upwards from the domain layer.
I then realized the utility of domain events and the fact that you can illustrate an entire business's operations on a timeline with domain events.
Designing systems from domain events instead of columns in a database, endpoints on an API, or components in a view, has so many benefits.
Here are just a few.
Communication
Thinking in terms of domain events is the closest we can get to expressing what happens in the real world. Features can be communicated by non-technical folk as a series of domain events.
UserRegistered -> EmailVerificationSent -> EmailVerified
Auditing & Reasoning
When we represent a system using events, we can reason about the way that the system changed over time since the current state is computed by applying all of the domain events that ever occurred. In some domains, this is mandatory for audits.
Estimates
Software can be a very creatively unbounded process. Find and count all the views
(read models) that present data and commands
(write models) that change the system and cause domain events, then measure their complexity.
The views and commands that a system needs in order to be complete are called "Use Cases" and adhere to the Command-Query Segregation design principle. Read "Better Software Design with Application Layer Use Cases | Enterprise Node.js + TypeScript" to learn more about how to design with use cases.
Scalability
Sometimes, in large applications- a single transaction might need to pass through or notify several other systems. In high-traffic scenarios, instead of blocking an async call, we introduce "Eventual Consistency" as a way to enable systems to "catch up" eventually.
Complexity
Business rules are often missed in CRUD-first design. In order to avoid unmaintainable if
and else
statements and anemic domain models, think in terms of events, the commands they sometimes invoke as side effects, and the preconditions that govern how and when they can be invoked.
Conclusion
Event-based architecture seems to be the common place to go when the problem we're solving with software gets really large.
Unfortunately, there's a bit of a learning curve.
If you're interested in learning event-based systems, here's what I think the general learning path looks like:
- Get really good at one programming language to the point where it feels like breathing for you.
- Understand what an anemic domain model looks like and if you have one.
- Learn about Event Storming and how it can help you plan a project using events.
- Learn Domain-Driven Design concepts like entities, value objects, aggregates, and domain events.
- Learn about CQRS and why you would want to use it in your DDD project.
- Learn about Event-Sourcing
- Build an application using DDD, CQRS, and Event-Sourcing.
Stay in touch!
Join 20000+ value-creating Software Essentialists getting actionable advice on how to master what matters each week. 🖖
View more in Enterprise Node + TypeScript