Digital Transformation to Microservices – The Approach
I will start with a scenario where a large system is being developed for over a decade. With time, it has become a gigantic system with ideas from so many developers from time to time and the team is finding it costly and time-consuming to maintain the system on daily basis.
The technology team and the management are very keen on a new buzzword called microservices. But it involves the cost of transformation.
How to go about this transformation? Is it worth it to go about the transformation or its good to continue with the current approach with some modifications? How to decide?
This journey of defining a microservice from a legacy system itself is a Legend.
Let us take an example domain of a POS application for a monolith/legacy system. It is a commonly understood domain for everyone.
It consists of the following broad modules built into a gigantic system:
How do we plan a migration for such a system? It may look easy when we migrate the entire system. But the business cannot wait till everything migrates.
There are some architectural challenges when we take an incremental approach and slice the domain into multiple vertical sections and migrate step by step.
I will explain some steps required to achieve your microservices goal. All the steps need not be sequential as mentioned. For example, 3 teams can take up Steps 1, 2, and 3 in parallel. I would recommend steps 1 and 2 are very important steps to plan before considering other steps.
The first step towards the microservices approach is planning the DevOps for your microservices. You should have continuous deployment methodologies set up for building, testing, and deployment of microservices as you are done with some features ready to deploy.
You can also look at containers and tools like Kubernetes for orchestration. Since it is a generic topic, we will not get into technical details and keep it open to choosing the technology of your choice.
Within this, the important thing to look at is API Gateway technology that can be used to compose several APIs.
The next important thing, probably the most important thing is to identify a Single SignOn technology that will be used for the new microservices rewrite. This is critical since the other services will be independent and it’s very important to give a smooth experience while browsing the application for different microservices with a single login.
The next step towards rewrite is to identify the vertical business domain subsystems in the system. In our example, we have customer, cart, product, promotions, payment.
I recommend you go through the Domain-Driven Principles of Eric Evans to create a framework for identifying a core domain and supporting domains in a system. It is also important to understand the Bounded Context principles in-depth to split a domain vertically into decoupled layers.
Out of these business domain subsystems, suppose the first domain you pick to rewrite is promotions.
What is the advantage of choosing promotions modules as the first rewrite?
The team’s acquaintance with microservices may not be matured in the beginning. So, picking a very core to business domain component like a cart, the payment might be riskier in the beginning. And at the same time, the core business will still need to run in the legacy system and for some time, other supporting or secondary domains can be integrated with the legacy system without a tight coupling and can be made run integrated with the legacy system.
In the process, keep your dependency on the monolith as minimal as possible and the module must be decoupled from other services. There may be some rare places where dependency may be required. For that expose a new API from the monolith, and then access the API through an API Gateway in the new service.
Slice your data layers also as per your vertical slicing of the domain. Remember, everything in the microservices is meant to be kept decoupled from other services. It’s important that along with UI and API layers, the data layer is also made for the given microservices without any cross-references. This is also important to build and deploy the microservices independently at their own pace without waiting for the other services to be completed.
The principle to slice out the microservices from the legacy should keep its focus on the functionalities rather than decoupling the code and extracting the code reuse from the monolith. Focus on rewriting the capabilities and get rid of the old code. The reasons being:
- Existing code depends on a lot of environmental dependencies, such as configuration at runtime, data stores, caching, sessions, and uses old frameworks. Most of this code needs to be rewritten. The new infrastructure to host a microservice will require a very different kind of boilerplate code.
- Existing code may not be written with clear domain concepts. This results in retaining the data structures that do not reflect the new domain models and require undergoing a big restructuring.
- A legacy code that has gone through many changes and life cycles of development could have a high code toxicity level and low value for reuse.
Then comes planning for the next module that needs to be taken up. By this time, the team also will be well conversant with the microservices transition. Teams can make the transition in the order: Payment, Cart, Product, Customer. I have considered the customer in the end because it has a dependency in all modules and the dependency back to legacy will be minimal since the cart uses the other dependency as master data. You may consider some of the modules to be developed in parallel and continue maintaining it with respective teams. In any case, teams should keep the design goals in the order given above for a smooth transition.
There are still challenges when designing individual services. As the amount of architectural code can bloat very easily. Flexbase helps to simplify this aspect.
FlexBase generates 60-80% of plumbing code for your functional requirements and is very useful while following Step 5 explained above. With Flexbase the process of transitioning to microservices becomes easier and less error-prone.