Summary: This article argues that there is an important step when switching from a Monolith to Microservices : Creating Modules.
Microservices are the rage nowadays, and for good reason.
Martin Fowler has written these lines about Microservices on his website —
…the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable…
…which may be written in different programming languages and use different data storage technologies.
Experts however also argue that you should not go for Microservices unless there is a valid business need. Unless your project has significant domain complexity and scale, going for Microservices will force you to waste more time and effort rather than save it. When you know you might need Microservices in the future, it is prudent to start with a Monolith, and then break up services in future.
Monolith to Microservices : The Problem
There is a problem on the path that leads from Monoliths to Microservices — Weak Module Boundaries.
What do I mean by weak module boundaries? It means the code is all dependent on each other, and thus difficult to split.
Take for example a service in your e-commerce application called PaymentService. It seems like an independent service, that at some point should be broken into a separate Microservice.
At some point though, a developer introduces a method inside the PaymentService that makes it dependent on the order and the user.
Now your Payment Service is no longer independent. In future, when you want to extract PaymentService as a separate service, you will face problems.
These dependencies gradually increase over time, and reach a stage where the classes are all dependent on each other. This is called spaghetti code.
Starting with Microservices: The Problem
There are two problems associated with starting with Microserviecs :
- It is Expensive. We now have to manage multiple applications. These apps would have their own databases. They would have separate deployments. The communication between applications becomes more expensive, which would lead to more server costs. Developers also have to write more complex code to achieve the same goals.
- The domain takes time to evolve. Take the Interleap application. Should courses be in a separate service? Where do the subscriptions go? How do we associate a user to a corporate subscription? We had not even decided that a course will be broken into sections and lectures.
If we had used Microservices, they would have significantly slowed us down. I am quite sure we would have created services, only to merge them back because we got the boundaries wrong.
Monoliths to Microservices: The Missing Step
There is a way you can go with a Monolith, but at the same time avoid the spaghetti that comes along with it : Modularisation.
When you see a piece of code that you feel should be an independent service (such as Payment Service), create a separate module, and add it as a dependency to your main module.
This will prevent you (and your team) from carelessly introducing dependencies into services that should be independent.
The other advantage is that it is easy to go back: If you realise something should not have been a separate module, you can easily remove it, and merge the files back into the main module.
When you start a new project, don’t start with Microservices. However, start with a setup that allows you to support multiple modules. Build a culture where the team feels free to extract a separate module for anything that seems independent.
Having multiple modules will help you divide your code into independent units, and make scaling easier when your app becomes complex, even if you don’t end up breaking it into multiple services.