As software engineers and architects, we are often faced with the challenge of creating a target microservices architecture for a legacy system. These systems are often big monolithic applications that have been around for years, often with lots of dependencies, and usually with no one person in your company that understands it all. In these situations, a collection of domain experts are key to understanding the “why” around the business context and capabilities that are needed, context which is critical to creating a successful architecture.
Typically, you start by creating a business capability model or taxonomy to map out the business capabilities and align them under specific level groupings. The overall model/taxonomy represents the collective set of capabilities needed by an application.
While this is helpful, it has some gaps. The taxonomy by itself doesn’t provide the broader context of the use case, it also doesn’t provide insight into how to decompose the capabilities into microservices. This is where event storming can help.
Created by Alberto Brandolini, event storming is an interactive way to do Domain Driven Design (DDD) that brings together domain experts across business and technology departments. In this article, I will provide an in-depth iterative example of event storming, some lessons learned using it, and how you can apply it to your architecture work.
What is Event Storming?
First, I want to clarify some common misconceptions around event storming.
Misconception #1 - It’s the Same as DDD
While event storming is based on a number of DDD concepts - including bounded contexts and aggregates - formal DDD can tend to be complicated and requires extensive training. Event storming focuses on an interactive collaborative whiteboard exercise that engage all domain experts. It is simpler and does not require extensive training like formal DDD does.
Misconception #2 - It’s the Same as Design Thinking
Both event storming and design thinking leverage interactive business process mapping exercises and whiteboarding. Where they differ is that event storming focuses on the decomposition and categorization that defines microservice architecture. It’s also focused on the things that are currently happening in the business process, known as events. Design thinking involves a phased process that includes problem definition, needfinding and benchmarking, ideation, prototyping and testing. It also focuses more on empathy and pain points.
How the Event Storming Process Really Works
Now let’s dive into the details on event storming. One of the first things to understand are the different types of details that are captured about the domain. These different types of details are typically represented by different colored sticky notes.
Let’s walk through each of these in detail.
- Events (orange): These are the most important and widely used component in Event Storming and represent the domain events and anything that is relevant to a domain expert. They are written in past tense and provide the underlying details that feed into the later categorization steps.
- Commands (blue): These are requests to do something. They can originate from a user or system or by another event.
- System (pink): These represent systems involved in the domain. They may issue commands or receive commands along with triggering events.
- User (yellow): These are human users involved in the process. They may be a single person or a department/team. Yellow sticky notes help show how complicated the workflow of a business process can be based on the number of departments involved and the amount of back and forth.
- Aggregate (tan): This is the first level of categorization and can be thought of as the “thing” that a group of events operate on. Typically they’re a noun and can be identified when there’s a cluster of events dependent on one another.
- Read Model (green): This represents data that may be critical for a user or system to make a decision. I have not seen this one used often, but it can be helpful when there needs to be emphasis on what data the user sees.
- Policy (grey): These represent standards or rules that may need to be executed, such as rules for a compliance policy.
Now that we understand the different types of details we want to discover in the domain, let’s walk through each of the iterative steps of event storming with an example. For our example we will model the domain of a generic e-commerce site.
Putting the Process Into Action
Step 1 - Event Discovery
The first phase of event storming is that of event discovery. Basically, everyone in the room is writing events and putting them up on the wall. Treat this phase like brainstorming so avoid applying any analysis or filtering at this stage as it will just slow things down. Don’t worry, there are later steps in the process that will clean things up.
This step usually takes the longest and it’s important to allow enough time for the foundation of events to be captured. Using the e-commerce site example, some possible events could be things like order submitted, payment processed, or inventory updated. An example of the output from this phase would look something like the below:
Step 2 - Placing the Events in Sequence
The next series of steps help identify any missing events by placing the events in sequence (typically left to right). Once the order is established, you can go backwards to help identify additional events. In our e-commerce example, the order information is entered first, followed by the inventory being checked. While putting them in order we discovered we left out an event for the input checks being performed. TIP - When multiple events happen at the same time, you can stack them vertically, such as below:
Step #3 - Modeling Out the Broader Ecosystem
After putting the events in sequence, the next step is to model out the broader ecosystem surrounding the events by asking questions such as, “What triggered the event? Is it a system? A user? Another event? What commands are involved?” This additional context is very valuable in understanding the current state of the domain. In our example, a user is what triggers the order information entered event and they do it through the webpage (system).
Step #4 - Simple Categorization of Events
At this point, all of the detailed events and their related parts should be modeled as you prepare to move into categorization.
The first categorization is known as aggregates. These are the nouns, or the things, that the events operate on. DDD also has a concept of entities, which you can think of as the next level down from aggregates. From my experience, treating the aggregate and entity as the same helps simplify things, making it easier for folks to understand. In our example, Inventory, Order, Offer are all examples of aggregates. They are the things that the events are operating on.
Step #5 - Bounded Context Categorization of Events
Now we are ready for the bounded context level of categorization. All related events would fall within a single bounded context. For example, all events related to a shopping card would fall within a shopping card bounded context. An important microservice concept to keep in mind here is if it changes together it should go together. We want to eliminate dependencies across bounded contexts as much as possible. If the language changes between events then that is a sign that you have crossed into a different bounded context.
For example, when moving from viewing promotional offers to checkout the language is changing. This is best done on a white board and you can simply draw an outline around the related events and label the bounded context appropriately.
Step #6 - Putting it All Together
Now we have completed the event storming steps! You can now use both the bounded contexts and the aggregates to understand the microservices needed. Typically, an aggregate within a bounded context represents one or more microservices.
In our example, the Order Capture bounded context will have microservices related to both Order and Inventory. You will notice that Order also exists in the Shopping Card bounded context and Order Fulfillment bounded context. This is okay, as it indicates they are different microservices since they are in different bounded contexts. They may both be doing things related to an Order, but what they are doing is different. In a monolithic application these would be bundled together creating coupling, but with a microservices architecture we separate them for independence.
Additional Step #7 - Create Capabilities
Now you have a great amount of information to help start your target architecture. In my experiences, I’ve found it helpful to add a step that creates capabilities from the events. Typically, the capability is the event just in present tense form. The capabilities can then be mapped to bounded contexts and aggregates in various target capability architecture views. These various views provide architects and engineers a well-thought-out blueprint for building their target state.
I hope you find this blog helpful. I have used this exercise many times and it is a great way to initiate a microservices modernization effort. It helps bring various domain experts across your company together, and educates everyone on the full end-to-end business processes involved. With event storming you can decompose the domain into small pieces that can be reassembled into the target microservices architecture that you want to define.
So go forth and decompose the monolith!