The strangler pattern is a common approach to rewriting, modernizing and migrating existing (legacy) software to a new approach/solution/implementation. We already covered some topics related with it in the past. Mentioned it as one of the alternatives for system rewriting, and described a case-study migration in one of our projects. But it seems, that strangler pattern is gaining more and more visibility in recent years, and this is not a surprise for us.
Strangler pattern comes with a good set of pros that it brings to a project. Also, the toolset that are now available to developers allow to easily perform this kind of migrations on living systems. Let’s take a deeper look at some basics, and the pros and cons that arise from them.
Strangler pattern approach
Let’s focus on the very basics first. What does the strangler pattern mean?
Well, in this pattern, we start with a legacy system that we need to rewrite, modernize or migrate to something newer. Quite often such legacy systems use some outdated technologies, frameworks, libraries, and their overall complexity makes it very hard or even impossible to refactor the code bit by bit.
Our first step with the strangler pattern is to put an intermediary facade in front of the old system. In that case, all requests need to go through the facade, before they reach the legacy system.
As a next step, we decide what part of the system (what service) we would like to migrate. Let’s assume we work on an e-commerce system. We could decide to migrate the home page first. In that case, we write this part of the system from scratch, using a greenfield approach. You can choose the tech stack, the architecture - everything. There are no major constrains. In our case, we usually decide to use Symfony, and an event-driven architecture.
The new system is built next to the old system:
When the team is finished with the development, and the new code is tested, we can adjust the facade and move the traffic for home page from our old system to our new service.
Following this approach, we can migrate the legacy application part by part. There is no need to work with the legacy code, all new features can be implemented in the new system. You maintain the old application, and at the same time add functionality to the new system. By following the strangler pattern approach, you can pay back the technical debt and add new features at the same time. Eventually, the new architecture will be completely replacing old code.
Pros and cons of strangler pattern implementation
- Minimize risk of migration by splitting the migration process into smaller, separated chunks of work. Divide and conquer!
- Allows to quickly deliver business value and achieve visible results - rewriting a small subset of features takes significantly less than rewriting the whole system.
- Has no major constraints regarding the software architecture and technology behind the new system.
- In most cases, the development effort required to rewrite the entire application is lower than in other approaches
- Easy to implement and understand. The code complexity is rather low.
- Works well even when refactoring a complex system.
- Allows to implement microservices architecture and split the work between multiple development teams. But as there are no constraints on the software architecture, you can also apply it to a monolithic application.
- Requires a lot of attention to the boundaries between old and new parts. Connection points, data exchange, etc.
- As a result of the above, might require to write lots of Adapters.
- It is quite easy to break some best practices and end with a dependency hell.
- Sometimes rollback scenarios might be hard to implement, and you obviously should have them.
- When implemented wrongly, the parts might become tightly coupled.
As always, using a software pattern comes with some consequences. You literally exchange one problem for another one. There are no silver bullets, but by knowing different approaches you can decide on what problems mean less risk for you.
In case of strangler pattern, you exchange the huge risk of rewriting a legacy monolithic application into smaller, less risky changes. You iterate faster, in a more agile way. There are obviously some consequences that arise, and you should be aware of, but smaller failures are always easier to fix, and that's what the Strangler fig pattern offers you.