Martin Fowler has a famous talk from the goto conference from 2017, where he breaks down event driven architectures, defining four common usage patterns. I, like many people, find myself leaning towards event-driven architecture regularly, with varying motivations and implementations each time. For this reason, I was curious about Martin Fowler’s opinions of event driven architecture and the patterns that he has identified, including:
Event notifications are the simplist event driven architectural pattern identified in the talk. The concept is intuitive and fundamental to event driven architectures. The primary reason for event driven architectures is the decoupling that is achieved, by reversing the dependencies. Fowler using a great example for explaining these patterns.
Consider an insurance system made up of multiple parts, a customer management system and a quoting system. A customer may change their address through the customer management system, in which case a new quote will be required. This would mean that the customer management system should trigger the insurance quoting system to recalculate the quote, coupling the two subsystems together. Instead, we can reverse this dependency through an event notification. That is, an address change event is triggered, with which the insurance quoting system is notified of the change and can determine what action is required.
With this we have the baseline of an event driven system, however the types of architecture used are determined from further extensions. For example, we can ask the question of, how much information should we include in our events? Do we include all the users old and new information, or just simply state that the users details have changed and let the quoting system ask for more details? This is the differenciation between event notification systems and event carried state transfer.
Event carried state transfer (ECSF) extends event notifications by providing all the information that listeners will need. In the case of our insurance system, the customer management system would give all the context that the quoting system needs, so that the quoting system doesn’t have to request more information. This makes event payloads larger, but reduces traffic to the customer management system. If the customer management system simply said, ‘someones address changed’, then the quoting system would need to request more information before it can complete a requote.
This approach has some pros and cons. Firstly, it reduces the load on the system emitting the event (the customer management system in our case) by reducing the amount of ‘extra information’ requested. ECST can also increase availability by reducing the level of which the quoting system relies on the customer management system. I.e. if the customer management system is slow the quoting system is less effected. However, this higher avaliability is somewhat counteracted by a decrease on consistency, due to replicated data.
Event sourcing is the most interesting pattern to me. Event sourcing means that the state of the application is stored both in the application state and as a list of all the events which have (over time) caused the application to reach its state. For example, lets say that the customer management system includes information about a customer Jane. Jane’s initial address is 123 Fake Street, then she changes her address to 456 Real Road. By keeping trace of these two events (and their order) allows us to derive where she now lives from a log of the past events. This is event sourcing.
Version control (e.g. Git) is perhaps the most common example of event sourcing for most developers. The idea being that each commit is a change event, whose payload is the diff is this case. By replaying all the commits of a repository, we can always derive the repoitory’s state. Another event sourcing example is accounts legers. That is a list of all the debits and credits of an account, which in turn derives an account balance. Event sourcing also uses snapshots to save the state of the application as of a certain time, similarly to closing a year and starting the next years accounts based on only that year’s transactions.
Although I’ve used many event sourcing systems, I have never directly developed one, which is definitely something I am interesting in. Especially so, considering event sourcing is a very powerful tool for collaboration.
Fowler only touches on the final pattern very briefly, however it does show a different usage of events. Command query responsibility segregation (CQRS) looks at events through a different lens. CQRS is where reads and write to an application state are handled by seperate systems. This allows each system to be optimized for it’s single job. This means that a system which may want a different domain model for read and write operations can have the two models defined seperately, and use events from the command (write) system to trigger state changes for the read system. This idea is only touched on briefly in Fowlers talk but is an interesting concept to look deeper into.
Overall, this talk provides an interesting insight into different patterns where event driven systems are used. While I have written systems which use some of these patterns, I considered them all to be simply event driven. Considering the differences between the 4 patterns Fowler discusses allows an extra level of specificity ontop of the general phrase event driven, therefore simplifying the design process by applying the right pattern to each problem.