From monolithic to microservice or monorepose
You may find a pattern whenever a new developer joins a company with a monolithic repository as a backbone. A pattern starts with the need to organise monolithic code better. Developers often find the need to jump to microservice architecture because it is highly modular and segregates the responsibility to its core. But what they don't realise in the beginning is the complexity it adds to maintain them. The segregation comes with its flaws and teams often find themselves in situations where they don't know how many teams are responsible for supporting a particular microservice. This tends to overlap the domain/business responsibility often. And the pace of delivering features starts taking time.
What are the problems moving from monolithic to microservice?
- Migration adds a cognitive load while developing new features.
- Maintainability and complexity increases.
- Infrastructure and DevOps workload increases exponentially. Especially, finding bottlenecks when the services face latency issues.
- Bugs are distributed that hamper debugging because it isn't clear which service might have the issue.
- Product Managers find it difficult to evaluate and tag the right team to look into a bug when multiple teams maintain connected microservices.
Here I'm not discouraging to take steps moving towards microservice architecture. The point is, to evaluate and make strategies based on the business needs and scalability required for the future. Choosing architecture or approaches only because there is hype, and seen as "one fit for all" often undermines the need to be critical.
Possible reasons for moving to microservices.
- When we know a problem that needs to be bound from several parts of the business and needs to play a centralising role. This problem is big enough that a team can be dedicated to maintaining it in the future. For example, Payment management in complex billing domains. Subscriptions are crafted based on users' needs. This means the invoice generates deals in managing credits, feature usages etc. Even in such cases, it is still viable to look into existing service options that can be incorporated within the application before we start planning to create a payment microservice. Many services like younium.com can play an alternative role so that the product team is focused on solving business problems.
- A problem that plays a core role in the business. This core business issue can't be outsourced and plays a vital role in exposing and connecting other parts of the system including external sources. For example, an API that can be incorporated with different businesses all around the world. Let's say our core domain is to manage contracts. Here we need to provide API for our clients to incorporate with their system to put them in sync. Then it becomes a business need to develop a microservice that can provide contract updates for external use.
Overall, business dictates the need to have microservice or avoid it. If businesses have funding in the future to maintain those services separately then it is possible to build those services. If the decision to have microservice is just because we want to have an organised code or segregate logic based on their needs then it is best to first look into the modular approach before extracting them into microservice.
Possible reasons for moving to Monorepose.
Imagine monorepose is the first thought before we start shaping architecture for microservices. Monorepose gives us the modularity needed and at the same time helps to provide teams autonomy to shape their domain according to the needs they face.
Considering we have an unorganised monolithic environment with MVP architecture. Within that, there is one app
or src
directory and all the files are pushed into it. Now this app
folder has more than 30 folders with names such as Requests
, Controllers
, Events
, Models
etc. Model-View-Controller (MVC) is the standard pattern provided by the majority framework to initiate development. In the frontend, it has become popular to use MVVM architecture to organise code. Back in the days of jQuery, developers mostly care about having file-oriented code segregation. Examples: utit.js
, common.js
, scroll.js
global.js
etc. These folders additionally have 100 files and many of them have 5000 lines of code. As teams grow, developers realise the code may get polluted so much that we should find a way to manage them. After some tech meetings, they either start rewriting code to a new microservice or keep the monolithic as it is and start creating new files within the same directory. Here we aren't solving the technical debt, instead shifting the technical debt to the future. When microservice is old certain features and connected features are still in a monolithic repository then the "source of truth" issue arises.
Monorepose helps to see our application more than the standard framework provided in the open-source community. If combined with Domain Driven Design they help us to think critically and ask questions on the roots directory we create and their existing. We start moving into the modularity direction and then the 50000 files accumulated within the app
folder start making no sense to keep contributing there. If we take Google as an example then there are GBs of code organised in a modular way within their main repository. One can ask, why they didn't find the need to move their code into the microservice way. It is good food for thought and there are other companies as well who still maintain their code within one big repository.