From monolith to distributed monolith

Ürgo Ringo
Wise Engineering
Published in
4 min readJan 30, 2019

--

Ouroboros

Probably one of the biggest risks in splitting up a monolithic application into microservices is ending up with a distributed monolith. In the following post I will talk about two friends of distributed monolith — microservices based on enterprise domain model and technical microservices.

At one point the negative effects of having large team work on a big monolithic codebase can become very painful. When this happens the goal of getting rid of this BigBallOfMud may easily become on objective of its own with less regard to what it is being replaced with. Anything seems better as long as it’s smaller. Especially if it is something with as strong positive image as microservices.

Surely if we have microservices we will not be susceptible to any of the problems SOA had because… well, because we have microservices.

Unfortunately there are cases where new acronyms and additional layers of technology cannot change the underlying principles.

Microservices based on enterprise domain model aka entity services

Our monolithic application has typically single database and single domain model. For example, it might have things like `User`, `Order`, `Product`. Generally there is one Entity for each table in our database. These Entities have typically quite little business logic while most of that logic is implemented in Services. All these Entities are probably connected to each other forming one big graph.

Now when we start thinking how to split this into smaller pieces then it might at first seem quite natural to split it around these Entities. After all we probably already have classes like `UserService`, `OrderService` in our codebase. Perfect, we already know what microservices we need to extract.

The problem with this approach is that we just end up recreating the very same enterprise domain model all over again. Only this time it will be distributed. Our new model will include all the dependencies between services that we had before between Entities in our domain model. We have just replaced local method calls with remote calls.

Is there a difference?

Also just like our co-located domain model this new distributed model will be based on data and not behavior. So most likely we will have each microservice responsible for some piece of data in our enterprise data model but it will not be able to implement any reasonable business capability by itself. The problem is that data by itself is never enough. It is the behavior built on top of the data that gets some job done for the customer.

Sometimes these entity services may have different names. For example, they may be called “core services”. This is particularly dangerous name cause it legitimizes the use of entity microservices and makes it even something desirable and required as part of the overall system architecture.

Technical microservices — workflow/orchestration/aggregation services

With “core services” we can say that these services only deal with the “core stuff” like basic CRUD. Then obviously we will need something else that deals with the more customer facing functionality. This leads to creation of entity service’s happy cousin — workflow/orchestration service. These services are analogous to Transaction Scripts that we had in the original monolith.

There are also other kinds of technical services. Good way how to recognize such microservices is to ask what are their responsibilities. If the answer is something like: “it manages events” or “it creates index of customer data” or “it aggregates orders and product details” then we can suspect it is a technical service. Yes, there is definitely a place for such technical services — just like inside a monolith we have services that take care of infrastructural concerns. However, the main point is that these services should be secondary to the overall architecture. Often they are just implementation details that should be hidden from the outside world. If we think about it then it is quite common that single microservice consists of multiple processes — like database, cache, indexing engine etc. The fact that sometimes some of these technical components are custom built does not mean we should elevate them to be the primary elements in our system.

P.S. Interested to join us? We’re hiring. Check out our open Engineering roles.

--

--

Ürgo Ringo
Wise Engineering

Have been creating software for 20 years. Cofounded a software consultancy, worked as an IC and team lead at Wise. Currently working at Inbank.