Cloudy with a chance of Event Storming

How we are using a Domain-Driven Design approach to our serverless architecture

Monique Grinstein
Engineers @ The LEGO Group
8 min readAug 23, 2023

--

Photo by NOAA on Unsplash

The calm before the storm

Joining a brand new squad can be the most blissful experience, especially here at the LEGO® Group. Squads here have a funky team name, mascots carefully crocheted for them, and really cool missions. I was twice as lucky as to join “Pirates,” a newly-formed squad working on a dedicated repository and AWS account.

Pirates’ mascot and “Pirate Adventure Ride” set — photo by me

Having the opportunity to develop a solution on a new codebase can lure one into thinking it will be simple to make everything perfect this time. State-of-the-art only, best practices, a fresh Jira board… The stage is set for coding nirvana.

Plot Twister 🌪️

This drive to attain perfection can soon be overtaken by a sudden existential crisis when it is time to start placing those metaphorical 0s and 1s. I mean, where do we start building? Have the other squads understood where we are going with this? Why do I feel like we have forgotten something major that will inevitably break prod when we least expect it?

As brave Engineers, we face those fears at the LEGO Group with a strong will and some doses of caffeine.

EventStorming

As a means to reflect on how to build our end-to-end system model and avoid expensive, misaligned software development, we have come across EventStorming. In this post, I am going to share what we have researched about said technique and the steps we are planning to take to try it out.

What is it?

EventStorming is a workshop activity. Everyone participating in the system somehow is invited: developers, domain experts, and business decision-makers alike.

It is also important to have the stakeholders from interfacing squads present — they will be able to help decide scopes and who takes care of what, as well as provide the point of view of “what comes next,” i.e., what are the boundaries and limitations for our system, as well as its possibilities.

As an example, we will use the AWS Cafe Business scenario (yes, I really meant it when I said caffeine would help us with this). Managers, cashiers, baristas, and waiters alike gather around and start storming out those crucial events standing between customers and their favorite roast.

Photo by Joshua Rodriguez on Unsplash

Forget JavaScript — hello, Ubiquitous!

If we want to build this system well, everyone involved must understand what we are building. For that, we employ a Ubiquitous Language:

“Craft a language to crisply express a set of problems and their solutions at all levels from domain expert discussions through code.”

— Eric Evans on Ubiquitous Language, DDD Europe 2020

This is imperative for aligning requirements (arising from all parties involved) and software delivery. Therefore, we build and keep the same vocabulary among all stakeholders.

“It’s developer (mis)understanding that’s released in production, not the experts’ knowledge.”

Alberto Brandolini, creator of EventStorming

Storm it!

A method in the madness

EventStorming might look like a frantic sticky note competition, but it is about quality, not quantity (although you do get points for completeness). Everything that goes on the board has a purpose, is color-coded, and is particularly arranged so that we can tell a well-defined story.

Color coding pattern for main EventStorming concepts on Wikipedia

Domain Events

We start by capturing Domain Events around the Business Domain we are working on and arrange them within a timeline.

In our example, the Business Domain is our Coffee Shop business, and to map its Domain Events, we have to think of the things that happen in the Coffee Shop that other parts of the operation must be aware of. Let’s see how our stakeholders stormed those on our virtual board:

Events at a Coffee Shop scenario — Image by AWS Samples

Now, we have mapped all events required for a typical Coffee Shop sale, which goes from offering a menu to the customer to having a table clean and ready for the next one.

Commands & Roles

After events are placed, we must identify what are their triggers (Commands) and who is involved in them (Roles). Thinking in software terms, one might be inclined to place Roles as simply “client” (customers) and “server” (shop staff). However, as our perspective comes from the Domain, we must characterize each Role according to which part they play:

Commands & Roles — Image by AWS Samples

We have now derived the Commands for each Event and identified four Roles at play: cashier, customer, barista, and waiter. In more complex scenarios, different flows for different Roles might also arise, and we would want to map those as well.

Aggregates

Some cohesion between groups of Commands and Events should start to transpire in such a way that they can be collectively seen as a single unit within the business process. In EventStorming, those logical groups are called Aggregates.

For our Coffee Shop, we have such units for Order Placement, Payment Management, Order Fulfilment, and the Shop’s Infrastructure.

Aggregates — Image by AWS Samples (modified to include Aggregates)

These also correlate to how teams should be organized and how responsibilities are spread across collaborators.

Bounded Contexts

Aggregates alone already help us identify different sections of our business. However, some Aggregates could also be grouped together, forming a “meta-aggregate,” as they are cohesive and could be seen as encapsulating important parts of the system. In Domain-Driven Design, those are called Bounded Contexts.

“A defined part of the software where particular terms, definitions and rules apply consistently.”

— Eric Evans, author of Domain-Driven Design: Tackling Complexity in the Heart of Software, on Bounded Context, DDD Europe 2020

For instance, at our Coffee Shop, Order Placement and Order Fulfillment can be seen as being within a greater boundary (i.e., a Bounded Context) of Order Management.

Discuss & Define

As we collectively build our board, some other crucial definitions should be discussed, such as:

  • Interfaces with external systems (which can also be third parties);
  • “What ifs?” and corresponding edge case flows;
  • Risky events and corresponding flows;
  • What software to develop in the context of the domain:
    - Business differentiator: core to the business —we build it ourselves;
    - Undifferentiated heavy-lifting: generic — delegate to third-party solutions;
    - All in between: supporting — we must decide to either build or delegate.
  • Views (if applicable): visuals that users interact with to carry out a system routine. Those will be translated into components of our User Interfaces.

Enjoy the view

After all the sweat and tears, the final result is a complete, validated, end-to-end model of the system. More than that, everyone now understands the model thanks to collectively building it. At our Coffee Shop, all employees and managers understand what goes on at each stage and know who to reach out to for queries and support.

Also, the outcomes of our workshop are duly documented in a centralized location as a single source of truth for further reference and improvement.

When EventStorming is conducted with the intent of developing software, Engineers are particularly happy now because they g̵o̵t̵ ̵a̵ ̵t̵-̵s̵h̵i̵r̵t̵ ̵f̵o̵r̵ ̵a̵t̵t̵e̵n̵d̵i̵n̵g̵ ̵t̵h̵e̵ ̵w̵o̵r̵k̵s̵h̵o̵p̵ can easily translate Events, Commands, and all other concepts into serverless architecture.

Next step: EventBridge Storming

As hinted above, EventStorming helps us get our foot in the door for building microservices. There is an optional technical continuation of this workshop, called “EventBridge Storming,” which takes in the output of the EventStorming session as a basis to conceive serverless, loosely coupled, event-driven architecture. The name comes from AWS’ serverless event bus service, Amazon EventBridge.

“The focus is less on formal DDD, but in pragmatically structuring Serverless architectures based on EventBridge.”

Ben Ellerby, creator of EventBridge Storming

In his article “The power of Amazon EventBridge is in its detail,” Sheen Brisals goes through the differentiators of EventBridge, as well as schema structures that are used for publishing events with it. The event below is adapted from an example in said article:

{
...
"detail-type": "event",
"source": "checkout",
...
"region": "us-east-1",
"resources": [],
"detail": {
"metadata": {
"domain": "CAFE",
"service": "service-checkout",
"type": "ORDER",
"status": "SENT"
},
"data": {
"orderNumber": "123123123",
"customerId": "23hdfjdf-34ff-34ghj",
"customerName": "Jane",
"items": 5
}
}
}

In an EventBridge Storming, this would be a good example of how we could eventually translate our previously mapped “Order Received” event in our system based on the “Sent Order” trigger. The top fields refer to AWS-specific attributes (specifications here), and with the “detail” attribute, we can customize the event data we need to send through to communicate with different parts of our system.

At the workshop, when mapping events, the barista had wisely pointed out that item details must be included when sending an order through, mentioning special requests in particular, as wrong orders and unsatisfied customers are a certainty when those are communicated through shouts at the shop.

The said requirement must be reflected in the event. For that, let us add more information on the object for detail, including a new itemsDescription attribute, which will be an array of the items ordered (represented by objects):

{
"metadata": {
"domain": "CAFE",
"service": "checkout",
"type": "ORDER",
"status": "SENT"
},
"data": {
"orderNumber": "123123123",
"customerId": "23hdfjdf-34ff-34ghj",
"customerName": "Jane",
"items": 5,
"itemsDescription": [
{
"item-name": "espresso",
"quantity": 2,
"special-requests": []
},
{
"item-name": "double espresso",
"quantity": 1,
"special-requests": ["brazilian-roast"]
},
{
"item-name": "iced latte",
"quantity": 1,
"special-requests": ["almond-milk", "brown-sugar"]
},
{
"item-name": "decaf",
"quantity": 1,
"special-requests": []
}
]
}
}

With this customization, we now have sufficient information conveyed by this event for the next Command, “prepare coffee.”

Thus, to build the microservices corresponding to our mapped Bounded Contexts and fulfill our honorable mission to have a Coffee Shop ready to welcome customers, we could leverage the power of an event bus service and use structured events as the one above, associated with serverless computing capabilities, as well as any other required services and functionalities (databases, object storage, etc.).

Done and dusted

Phew, everything is now under control, and this Squad is ready to rock ’n’ roll!

…Or we hope we will be, as we have just finished our discovery phase of EventStorming and are yet to host the workshop session. Hopefully, my next Medium publication will tell you all about our successes in this one.

See you then!

Photo by Daniel K Cheung on Unsplash

--

--