The good and the bad of event bus in event sourcing
The event bus is a powerful design pattern in the world of event sourcing. It allows you to decouple the event producers from the event consumers. But it also has its downsides.
When I talk to people about event sourcing and ask them if they have already used it and have experience with it, I often get the same answer: they would like to use it in their next project. Sometimes they even already have some limited experience with event sourcing because they used it in a pet project. So, I always ask them why they hesitate. There are different answers to this question. Let's take a look at them and my opinion on each of them.
I'm always baffled by this sentiment, but I understand where it comes from. Event sourcing is always associated with its nicest feature: historical data. However, there is a misconception that you can or should only use it if you need historical data from a business point of view. This is simply not true - it just means it would be an even better fit for the project. I would even argue that if you need historical data, you should use event sourcing - really, you should.
So, what is the use case for event sourcing? To be blunt: every use case. Yes, this sounds stupidly optimistic, but in our world, everything works like event sourcing does. We react to facts - things that have happened. This also means that we can perfectly reflect the business at hand with event sourcing. In my opinion, there is no case where I would say to never use event sourcing. But, as with everything in life, there are advantages and disadvantages to event sourcing.
There are cases where event sourcing may not be the best choice. For example, a simple CRUD application that only provides one or two entities and some forms to be filled out by the users. But how often do we see these small applications grow into bigger projects? Yes, 90% of these applications grow over time and become more and more complex. Soon, this small CRUD application will provide a ton of features, most of which are built on a simple approach using anemic entities. This often results in significant complexity due to all the added business rules over time. And this brings me to the next topic - complexity.
Yes, I understand that event sourcing initially feels overwhelming and complex. But as soon as you get used to it, you will realize that many things become easier to solve, while others may become harder to address. I think the perception that event sourcing is more complex results from the shift in thinking when designing applications. You need to think differently than before, especially if you are not familiar with event-driven architectures. If you have little experience with these kinds of applications and have already developed habits in designing applications using other architectures, this can lead to the perception that it is more complex. If you have been working the same way for 10 years and suddenly try to do something differently, then naturally it feels harder and more complex. But this does not mean that it is inherently more complex.
Taking the example of the CRUD application, yes, it is more complex to solve it with event sourcing at the beginning. But as I mentioned, it is rare that projects really stay at this level of low complexity, only providing some interfaces for basic CRUD operations. As soon as we leave this area, I would say a DDD approach is always better than the basic CRUD way with anemic entities. I hope we are all on the same page here. And if we are already doing DDD and encapsulating the business logic, then the jump into event sourcing isn't as far anymore.
And if we are now talking about projects with some business logic involved, then, as already mentioned, there are things that are more complex to solve with event sourcing and some other topics that are easier to address. I will quickly go through an example for each case with as little detail as possible.
Defining your first events can be tricky. So what happens if I forget something or want to remove a property from my already existing event? First, we cannot update our event store because our events are immutable! But what then? We need to create a new event, a second version. Our code should then only create this new version but still needs to keep the old one. Why do we need this? This is because in our event store these old events still exist, and our application will consume them. Now you are probably thinking that this will lead to a lot of "dead code", but that is not necessarily the case. There are also techniques to prevent creating dozens of versions of your events, like upcasting. With this technique, the event will be altered before it is hydrated into an object. This can cover most of the initial design failures of the events.
A much easier task would be to track or audit historical data changes - jokes aside, that's what we all already know! I want to take another example: creating reports. With event-sourced systems, you can easily create different types of reports from the data you have, even for things that happened days, weeks, or even years ago. This is possible because you have all the data available, and you can create the right projection for specific use cases. In a classical approach, all data from the past would be lost. Maybe you could restore some of that by crawling through dozens of log entries, but that is tedious and not fun at all.
And you don't need them! Why should you need a greenfield project? You don't need to implement everything with event sourcing, you can just do part of the project with it. Yes, you can add event sourcing to an existing project without any problems. Especially if it is a completely new feature for the project, then it is even easier to do that. And if this new feature takes advantage of the benefits of event sourcing, even better! I already wrote an article on how to combine ORM entities with event-sourced aggregates, which can give a good first impression of how you can mix the two concepts.
Well, this one is simple: Don't force it - no one likes to be forced to do something. Instead, try to convince them by using arguments for why event sourcing is a good or even perfect fit for the project at hand. Especially in the first project, it makes sense if event sourcing feels naturally like a good fit. This makes it easier to handle the project for beginners. But as I mentioned earlier, event sourcing is not a niche thing, it's how our world works, it will fit with every project.
You can start with event sourcing in any project at hand, you don't need a greenfield project. You can integrate it into any already running project, whether by refactoring an existing part or using it for a completely new feature in the application. Also, you don't need the "perfect" use case! Sure, this makes things easier for beginners, but it is not necessary to try out event sourcing and get started working with it. Maybe this blog post helps to get rid of the misconception that event sourcing should only be used if we desperately need the historical aspect, and that if it is not needed, it would be too complex. I also plan to write a detailed article about integrating event sourcing into already running projects and on the benefits that event sourcing provides.
The event bus is a powerful design pattern in the world of event sourcing. It allows you to decouple the event producers from the event consumers. But it also has its downsides.
We are happy to announce the release of the php event sourcing library in version 3.4.0. This release contains several exciting new features and improvements. In this blog post, we will provide you with an overview of the changes.