Domain Events

Docler
Byborg Engineering
Published in
3 min readNov 5, 2019

Written By Umit Akkaya

More often than ever before we have to notify other systems and other parts of the application to know what has happened in our domain. Events are a great way of achieving this.

Let’s walk through how to place events into your domains in an easy way. In this post, we will focus on the part where the events are happening rather than the event listeners.

As an example, we are going to build a very simple online store with the following technical requirements: Users are allowed to add an item N times to their cart. We record events when User adds an item to the cart or pays for the order. Recorded events are sent out when we persist our User successfully.

These events can then be used to trigger shipment, and analyse what users add to their carts along with other items etc.

Before getting into implementation details, let’s take a look at the class diagram of our domain objects:

Domain object class diagram

We will use `order` method to add items to the `Cart`. and `pay` method to pay for the items in the cart.

We can start by implementing Cart and User domains:

User should be able to add items to the cart, so we need an `add` method in Cart and `order` method in User object.

User also needs to (pseudo) pay functionality for the items in their Cart.

Now it’s time to place our events within our domain

Our domain event interface looks fairly simple:

Overall Class Diagram

Now that we have our events we can use them in our User domain.

Our User domain now has `events` field along with the `pullEvents` method.

`pullEvents` method will give us recorded events that happened, it will also reset the events to the initial state, after events got pulled.

User Class

Event Creation

We modify the add method of Cart class and pay method of User class like this:

Now we are recording our events as they happen, but still we do not publish them anywhere.

At this point our Store service comes into play. Our `Store` orchestrates the checkout process by making the User pay, persisting the state of the User and publishing all of the events that happened.

And the checkout implementation looks like this:

You can think of user repository as just a persistence layer of abstraction over a database. EventHandler, however is much more interesting:

Responsibility of EventHandler is quite straightforward. It gets all of the Domain events, maps them to Messages and forwards them to the MessageBus.

EventMapper separates our domain events from infrastructure level Message logic. It also gives us flexibility to create attributes based on specific Events.

The MessageBus implementation depends on the infrastructure, but for example a simple Redis PubSub MessageBus looks like this:

Recap

As seen in the diagram below, our store is orchestrating the checkout process, User and Cart domains are recording events as they happen, and our event handler is responsible for publishing those events to message bus.

That’s all, now you have seen one of many ways of putting events into your domain logic.

You can find the example code I have used in the article here: https://github.com/umitakkaya/store

--

--

Docler
Byborg Engineering

Curious about the technologies powering the 30th most visited website in the world, with 45 million users, 2,000 servers, 4 data centers?