Transform monoliths to micro-services

Structured gradual Transformation

Disclaimer : The content of this blog are my views and understanding of the topic. I do not intend to demean anything or anyone. I am only trying to share my views on the topic so that you will get a different thought process and angle to look at this topic.

Micro-Services are most popular Architectural style today. Everyone wants to adopt it. New projects can easily do so but existing projects struggle a lot. All Businesses have certain obligations to ensure high availability along with upgrading a tech stack. Micro-Services are the key to Business Agility. I would like to share my views on this topic. How to effectively transform existing legacy Monolithic application to latest Micro-Services Architecture.

Monolithic application is the one which is a single deployable artefact. A single bundle with all features. Java has a concept of boundary separation using methods, classes, packages and jars. We know simple concepts that a code within same class shares same state ( i.e. instance variables ) but could be separated by methods. The methods and state define a class which adheres to the Single responsibility principle ensuring that the object of that class can perform defined actions based on its responsibility. When multiple classes start interacting with each other we create a new boundary to understand their grouping based on packages. For example - a repositories package will contain classes which help us with persistence layer. 

Code Boundary Separation
Code Boundary Separation

Code reusability was introduced by these separations but the code was reusable within same application. Java Archive ( JAR ) files help us bundle reusable code and share it with other developers. We came up with an abstract concept of modules to ensure code separation by features. Services concept was introduced to separate a code by execution environment. A executing code ( i.e Service ) can interact with other service following some contract. Modules concept was abstract so far but Java-9 onwards its more constrained now. Since without a proper constraint an abstract concept is not full proof. Why are we discussing about these basic known concepts and not about - How to transform Monolithic application to Micro-Services ? It's a pattern which I wanted to highlight to understand the process of transformation.

We humans understand things using similarities and differences. In the pattern mentioned above at every level we applied it. For example methods create a boundary and separate each other which represents differences but what should belong to a method is based on the similarity. A similarity factor which connects the code or logic to be implemented in that method. This concept is applicable at Class level, Package level, Module level and beyond.

Module Separation

In the transformation process, if you have this proper separation till Packages level then you have the required ground work ready. If not yet then please follow the above conceptual understanding and create these boundaries in your monolithic code. Now apply the Java-9 modular constraints in your code and observe below points :

You will get an early feedback when you apply above constraints using this JDK 9 modular approach. 

Once you have done these changes, still your code is monolithic but is gradually ready to be migrated. Next step in the hierarchy is Services. Modules are to be separated by execution environment. To achieve this we need to define Java interfaces similar to how you will interact with a Web Service. Once the interfaces are ready you should provide a simple implementation class in your respective modules since the code is still monolithic and needs to run on same JVM.

Database Separation

Now that modules are separated you need to ensure that the database schemas are separated. To achieve this you can start separating instances of database for each module so that it will help achieve separation with pure constraints. The database tables should not have direct referential constraint using a Foreign Key, instead there should be some loose coupling using some unique identifier like we do in Micro-Services. For example a Basket Id would be stored in the Order table but without any Foreign key constraint.

DATABASE SEPARATION
SERVICES EXTRACTION

Services Extraction

Next and final step would be to extract each module one-by-one as a separate service and resolve breaking stuff. We can use frameworks like Feign Client which can help in using interfaces approach to talk to a micro-service. Once the services are separately deployed I think you have successfully migrated to Micro-Services architecture.

Software Industry is evolving very fast but we need to adopt new technologies with some caution. We need to be aware of Business limitations and efforts we put in Developing a large project over a period of time. Refactoring an existing project and transforming it in a structured way is very important.

Although, one of the disadvantages of the Micro-Services architecture pattern is that the development complexity is increased. A developer cannot directly debug a code and see workflow or code flow across Micro-Service. I was thinking if we could preserve the Monolithic modular code during development but it will be deployed as a Micro-Services. We will get the benefits of both. Just food for thought !

KEEP THINKING !