In my project we start looking at a concept of streaming, to return a stream of response once data is available and not waiting to return a whole chunk of data. With use of Spring WebFlux, it is easy to make a prototype of the idea. And, this makes me come across a new programming model, Reactive Programming and later Reactive Systems.
I searched on the Internet as other developers would do and found this good series from IBM, Reactive in practice: A complete guide to event-driven systems development in Java
With this series, I will learn to design, develop and deploy reactive systems by using IBM’s Stock Trader reference architecture.
So, below are my notes from the series. Many are contents from the slides which already well summarized and defined. They are useful as guidelines when practicing on my own.
The contents in this post is actually about Domain Driven Design topic. Because it is the first course I took. Contents on reactive systems will come on later posts.
Why learning reactive systems?
We need a system that can handle fluctuating demand. Because of this we need a system that can scale out and back in real time, which helps keep operational costs reasonable.
So what is a reactive system?
Reactive systems are
- Responsive – provide rapid and consistent response times
- Resilient – stay responsive in the face of failure
- Elastic – stay responstive under varying workload
- Message driven – rely on asynchronous message-passing
Before jumping into the reactive topic, there is prerequisite knowledge we need
- Domain Driven Design (DDD)
- Event storming
which I’m going to summarize each topic below.
Reactive Architecture: Domain Driven Design
A course from a joint collaboration between IBM and Lightbend. You find an original course here.
We are going to learn about the fundamentals of DDD
- What DDD is
- How it relates to reactive architecture
- How to use DDD to decompose a problem domain into manageble parts
- How decomposition parts become the foundation of your reactive microservices
Domain Driven Design
The course focuses on modern DDD where the domain is designed around activities or events that occur in the domain, a so-called event-first domain driven design.
DDD is a technique to tackle a large problem, break it into smaller and manageable pieces of problems.
What is a Domain?
A domain is a business or idea that we are trying to model.
The goal of DDD
the goal is to build a model that the domain experts can understand.
Important the model is not the software. It represents the domain and our knowledge and understanding on a business or idea. The software is an implementation of the model.
Terms and concepts used in DDD
Parts of a large domain, are created by grouping related ideas, actions, and rules
It is a language understood by domain experts and used in models to communicate between domain experts and system developers.
It is the language and model for a subdomain.
Subdomains or Bounded Contexts are good starting points for building Reactive Microservices.
A Bounded Context may be broken down to one or more Microservices.
Below are good guidelines help to define context boundary
- Look for change in ubiquitous language. From one Bounded Context to the next the meaning of a word may change dramatically. For example, in a restaurant, an order placed by customers and an a restaurant’s order to suppliers.
- Look for varying or unnecessary information. The details of the model may change when in different Bounded Contexts. For example, in a restaurant, an order sent to the kitchen doesn’t need to contain prices but an order taken by a server, prices are very critical.
- Different areas of the domain handled by different groups of people, suggests a natural division
- An awkward workflow or has too many dependencies in the Bounded Context may signal a misunderstanding of the domain
Once we have clean and clearly defined Bounded Contexts, we have to pay attention so that one Bounded Context doesn’t bleed into another Bounded Context. This is why we should discourage an idea of abstraction of objects. Creating abstraction will create a coupling that we don’t want. For example, in a restaurant, Customer in delivery subdomain requires address but Customer in reservation subdomain only requires telephone number.
It is a tool we use to prevent the leakage. It will translate incompatible concepts in one bounded context to other bounded contexts.
Domain building blocks
Types of activities in the domain (domain activities)
- Represents a request to perform an action
- The action has not yet happened and it can be rejected
- Usually delivered to a specific destination
- Causes a change to the state of the domain
- Ex. Add an item to an order, pay a bill, prepare a meal
- Represents facts, actions that happened in the past
- Those actions cannot be rejected
- Often broadcast to many destinations
- Records a change to the state of the domain. Often the result of a Command
- Ex. An item was added to an order, a bill was paid,a meal was prepared.
- Uses a past tense to describe the Event
- Represents a request for information about the domain
- Must return a response
- Usually delivered to a specific destination
- Should not alter the state of the domain
- Ex. Get the details of an order, check if the bill has been paid
These Commands, Events and Queries form the API for a Bounded Context or Microservice.
Types of objects in the domain (domain objects)
By identifying activities, it also help us to define what objects we are going to interact with in the domain.
- A Value Object is defined by its attributes
- Two Value Objects are equivalent if their attributes are the same
- Value Objects are immutable
- They can contain business logic
- Messages in Reactive Systems are implemented as Value Objects
- An Entity is defined by a unique identifier
- An Entity may change its attributes, but not its identity
- If the identity changes, it is a new Entity
- Entities are the single source of truth for a particular id
- They can contain business logic
- An Aggregate is a collection of domain objects bound to a root Entity
- The root Entity is called the Aggregate Root
- Access to objects in the Aggregate must go through the Aggregate Root
- Transactions should not span multiple Aggregate Roots
- Aggregates are good condidates for distribution in a Reactive System
Determining the Aggregate Roots
If answers to the following questions are yes, that Entity is a good candidate for an Aggregate Root
- Is the entity involved in most operations in the bounded context?
- if you delete the entity, does it require you to delete other entities?
- Will a single transaction span multiple entities?
This is a placeholder for business logic when it doesn’t fit with Value Objects or Entities.
Services should be stateless.
If you have too many Services, this might be a sign of missing domain objects.
Factories and Repositories
- Factory represents a C operation, Repository represents RUD in CRUD operations
- Factories abstract away of a creation of a domain object
- Factories may require access to external resources (databases, files, REST APIs)
- Usually implemented as a domain interface, with one or more concrete implementations
- Repositories abstract away the retrieving of existing objects
- Repositories often operate as abstraction layers over databases, but they can work with files, REST APIs, etc.
Hexagonal architecture is used a lot in DDD. This is an alternative to n-tier architecture where groups of components are layered on each other. Often the top most layer is a presentation layer, then a business logic layer, a domain layer and a data layer at the bottom.
In DDD, we center our design around a domain, it makes sense to model our domain in the middle as a core of an architecture.
Hexagonal architecture has a shape of a hexagon or an onion where domain is in the core, then an outer layer is ports (APIs) that used to communicate with domain objects, then adapters (infrastructure) which communicate with the ports.
Dependency is a key here. The outer layer depends on an existing of the inner layer but the reverse is not true.
This mean the hexagonal architecture ensures a proper separation of the infrastructure from the domain
Steps in defining subdomains / bounded contexts
- Identify activities happen in the domain
- Group the related activities. After this step you should be able to identify bounded contexts
- Pick up one bounded context and translate activities into codes e.g. a command: Open an order, gets translated to OpenOrder. Event: Order was added, gets translated to AddedOrder
- Define objects. By identifying activities, we can define which objects the activities encounter. E.g. OpenOrder command interacts with an Order object.
- Add fields to objects e.g. Order(orderId, orderItems, tableNumber, serverId)
- Abstract away business logic from domain objects using different domain abstractions (components): Services, Factories, Repositories
- (Optional) Categorize those components according to hexagonal architecture, focusing specifically on the domain and infrastructure components
It’s 03:30. I couldn’t fall back to sleep.
When it’s like this often that something is going in my mind.
What is it this time then?
My rowing result. I still don’t achieve the result I want. I was thinking about to get there.
Jobs. I wonder hire it will be. What sold I focus? Too many interesting topics again. I’m distracted.
Kids. I need to focus more on them. Activities for them, Christmas calendar.
And so on…
I didn’t plan to make a move. In fact, I plan to focus and try on a technical track at least a half year.
Suddenly, these opportunities came to me. The first one I thought I just wanted to see how it would go. So I was not serious about it. It turned out I did it well in the interview. Even me I was surprised with my answers. I didn’t lie and was not exaggerated about my willingness and reasons I was there. It was my inner voice. My heart wanted it.
I am ready to take risk and work hard to cross what seems to be my limit.
It is the same as when I row. The only way to be able to row harder is to row harder.
The only way to have more responsibility is to take more responsibility.
I was thinking I would like to be an architect when I turned forty. I have a plan to get there but it was not what seems to be happening now.
Still it is too early to celebrate, I haven’t secured it and it’s too good if everything just falls into the way how I want it to be.
But if it is so, what could I say? I’m gonna celebrate my 40th birthday with tears of joy. It’s going to be a glorious year and I’m going to make it a glorious decade to come.
On top of that I have already started preparing one of the best presents to myself and it goes as planned.
Until everything reveals itself, let me think big and dream an impossible dream
Sometimes I just want to do as my youngest daughter usually does, saying “det kan jag” proudly.
The challenge ended on 31 October.
The last two days of the challenge I started to catch a cold with low infection in my body. And I had 15k meter left.
In the end I managed to collect 15k by rowing at very moderate intensity.
As a result, my name is on an honor board for persons who row at least 31k and a certificate.
A hidden agenda of my workout is to lose weight. I’m small yet overweight. That’s not a good combination.
Now I have been rowing indoor for two months, my fitness has improved. I can feel that and row with higher intensity but I still don’t lose weight.
So, I went back to review my workout logbook. Obviously, I exercised too little to lose weight.
Together with the holiday challenge by Concept2, I’m going to row 7k/day, 6 days/week with 10k on Saturday on moderate intensity.
Vary my workouts as followed
- alternating 1 minute of hard rowing with 1 minute of easy rowing.
- moderate 10 minute pieces with 2 minutes easy rowing in between.
- moderate intensity on 7k or 10k
Let’s see if I’m going to lose my weight.
I don’t feel being outside due to the language anymore.
At the moment I’m working at a multi national office where English is an official language when documenting and discussing work topics.
However, Stockholm office is still full of Swedes and they are happy when it is possible to use Swedish.
Today, for example, one was about to bring up a question in Swedish then he was unsure when he saw me. I instantly, confidently and comfortably signaled that it’s fine in Swedish.
Language is not a barrier at work anymore. It feels so good to be in this position. I have leaned a totally new language.
Just when I left the office today I got an idea that in this life I might move one more time and learn one more new language and culture. Eastern Spain, perhaps!
Now I have committed to an indoor rowing challenge taking place in october by Concept2.
The event is between 25-31 October. My challenge is to row at least 31,000 meters during the event and I plan to row just exectly that distance ^^.