Software architect — III — Legacy to Modern
Every developer in software industry must have encountered a situation to migrate a legacy old application in their organization having a traditional architecture like layered N-tier architecture, due to frequent maintainability, scalability and deployability issues they face whenever they get a change request from the product management, into a modern microservices architecture, but could not proceed as they couldn’t convince their product management in implementing such an overall architectural and design change, which involves more cost and time.
If your application is having too many dependencies and high coupling exists between the individual components, then you are dealing with a big ball of mud anti-pattern, where you have to get your hands dirty to release all the individually coupled code without affecting the existing functionality.
So how shall we proceed then?
There comes the savior design pattern — Strangler pattern
In Microservices architecture, modularity is the primary concern in terms of domains. So the same should be achieved gradually in such a traditional architecture by separating the concerns step by step, but not as a whole.
Strangler pattern
Migrate a legacy application incrementally by replacing existing functionalities into modern services in a phased manner. After replacing all the features of the application, the existing legacy application is phased out. The name strangler pattern is inspired by the strangler fig trees.
The challenge of implementing this pattern lies in analyzing the existing functionalities and dependencies, identifying the areas of separation and apply an efficient migration strategy. One should also consider the level of testing performed for the separated concerns and also the integration with the existing system. After the separation, deployment plays a major factor where the concerns are deployed and the function calls are re-routed to the new services.
Strangler Facade
As a first step a facade interface should be placed between the invoker and the executer. This interface should be re-routing the actual requests from the invoker to the new service in a current phase of migration. Consider you have the plan to separate the User management and Authorization into separate microservices, then introduce an interface which will be agreeing a contract between the User interface and the backend services. Some of the requests will be redirected to the new services through the façade instead of the existing service.
Once all the services are moved entirely to the modern microservices architecture, then the façade should either be removed or should permanently redirect to the new service.
The reason to maintain the legacy services still in the app domain is, to route the service calls back to the legacy system in case the new system fails for certain reasons and the old system acts as a fallback mechanism to make the availability of the services.
Usage
Strangler pattern cannot be used,
- If you have a very smaller system where the complexity and the size is very low
- where the backend service cannot be intercepted and routed
- where the façade should be causing a single point of failure of the entire system
P.S. MSDN has a reference to the strangler fig pattern.