Unleashing the Power of Event Storming

A Step-by-Step Guide to Designing Event Sourcing and CQRS Systems

Noah Hsu
Javarevisited
6 min readApr 15, 2023

--

pictures copied from https://tenor.com/view/open-gate-lotr-elves-rohan-gif-22076834 and https://coub-attachments.akamaized.net/coub_storage/media_block/cw_image/0e4904142c9/277466ca05593343f7a5c/1585921667_1o8jmtn_1585921640_vkwc70_att-url-download.jpg

After introducing what benefit can be brought into the system in my last article. I decided to build a Proof of Concept (POC) project with Event Sourcing and CQRS architecture. The first thing is to confirm the project's scope, and there is an excellent theory, Event Storming to do so.

Event Storming is a methodology for analyzing and developing the business flow of an event sourcing system. We should model our business logic flow with different kinds (event, command, actor…) of stickers. follow

This article will start with a brief introduction, and then show how to do so step by step, which contains

  1. Defining the scope boundary (start and end).
  2. Enumerating all the domain events in the scope.
  3. Defining the actor and command for each event.
  4. Adding external system and policy.
  5. Adding read models and UI.
  6. Link all stickers and separate them into different aggregates.

Let’s start!

Brief Introduction

There are lots of articles that cover the definition of Event Storming, so I will not do it again, but I will reference their contents and do a quick recap

Kind and Definition of stickers

https://ithelp.ithome.com.tw/upload/images/20190923/20111997GZdzTXl6ko.png
Event storming. (2023, February 1). In Wikipedia. https://en.wikipedia.org/wiki/Event_storming

note:

  • The “Actor” sticker is the match-man sticker in the first picture.
  • The “UI” sticker is missing in Wikipedia, but it’s quite straightforward. means it will provide a read model to the user.
  • The “Business process” is also called “policy” sometimes.

Event Storming Step by Step

1. Defining the scope boundary

This step is quite easy, just decide the scope of your system. It could be a start and end of a user journey. For my example, I decided to build a system that can handle a user’s order on an Electronic Commerce (EC) website.

So the first step will be the actor, “User” send a command, “create order” which will become an “order created” domain event. After the system handles the order, the user journey will end up when the “order completed” event occurred.

Defining the scope boundary

Then we can first draw ( I use miro.com) the picture like above. The remaining work is modeling the process during these two events in the next steps.

2. Enumerating all the domain events in the scope

Step 2 needs very strong domain knowledge since we have to try enumerating all possible domain events to connect the start and end events of this user journey. We can put as many events first, and then pick up the significant events, sorting and putting them in the business flow.

For my example, after we created the order, we have to create a payment for the order. after the payment is validated, we have to start shipping the product to the user by creating the shipment with some delivery vendor, monitoring the shipment status, .etc. After the shipment is delivered, we must check the payment is paid then we can say the order is completed.

Enumerating all the domain events in the scope

then put event stickers to the original business flow on Miro as above.

3. Defining the actor and command for each event

Step 3 is a relatively easy one. We only need to add the actor and command for the domain events added in Step 2. The actor is the one who sends the message/request to trigger some events.

In my example, the user (buyer) sends requests to create an order, create/confirm the payment, and create/receive the shipment. The system will validate the payment, settle the payment, and complete the order. Sellers will send messages to notify that the product is prepared or in delivery. The Delivery Center (DC) will sync the shipment status with the system or buyers by sending messages.

Defining the actor and command for each event

This step is to make sure which event should be triggered by which actor’s command.

4. Adding external system and policy

Step 4 needs to make sure the business logic is in the scope of the project or not. If it’s a logic we will handle, then we put it into a Policy sticker in detail; otherwise, put it in an External system sticker.

In my example, after a payment is created. There is a “Policy” that says:

when payment is created
then validate the payment info

This policy could connect the payment-created event and payment-invalid or payment-validated event by sending a validate-payment command. But, we are not interested in how to perform the business logic of validating a payment in our project, we will put such things into an “External System” sticker like “validate payment”. It will be calling a third-party or vendor’s API in the implementation phase.

Adding external system and policy

Following this logic, we can insert all the “Policy” and “External System” stickers into the flow. (I also modified the event slightly during Step 4.

5. Adding read models and UI

Step 5 needs to decide what data and structure you want to expose to the end user.

In my example, I should provide the users (both buyer and seller) query about the order, payment, and shipment status. And every event should update the “Read Model”. and the read model will be provided to UI.

Adding read models and UI

6 Separate them into different aggregates

Finally, we complete the whole business flow. Then, we should do one more work to categorize them into different “Aggregate” ( some will call it a boundary context in Domain Driven Design (DDD)).

In my case, it is very easy to divide them into three “Aggregate” which are “Order”, “Payment”, and “Shipment”, respectively. So we can refine the flow like below.

The meaning of specifying the aggregate is to clarify the domain object boundary. In a CQRS architecture, one aggregate should be implemented as at least one command-side and one query-side server.

Summary

In conclusion, Event Storming is a powerful methodology for analyzing and developing the business flow of an event sourcing system. By modeling the business logic flow with different kinds of stickers such as events, commands, actors, external systems, and policies, we can define the scope boundary, enumerate all domain events, define the actor and command for each event, add external systems and policies, and add read models and UI. This process helps to visualize the whole system and facilitates communication and collaboration between team members. Overall, Event Storming is an essential step to designing a successful event sourcing and CQRS system.

I’ve developed a POC project in my personal repository, feel free to get more details and the complete code here.

If you found this article valuable, please consider supporting my work by buying me a beer 🍺. Your generosity fuels my passion for creating more Event Sourcing and CQRS system content. Don’t forget to share and clap for this article, and follow me on Medium for future tech stories. Thanks for your support and happy reading!

--

--

Noah Hsu
Javarevisited

Java ServerSide Engr🚀, Focusing on Spring, Toggle system, Kafka, Event Sourcing, and CI/CD. Support my work with a 🍺. https://www.buymeacoffee.com/swbhcjhtyvv