Strangler pattern

Today's world is one where technology is constantly evolving. What is written today, is just tomorrow's legacy code. This pattern is very helpful when it comes to the migration process. This pattern is about eventually migrating a legacy system by incrementally replacing particular parts of functionality with new microservices application and services. It eventually introduces a proxy that redirects either to the legacy or the new microservices, until the migration is complete and at the end, you can shut off the strangler or the proxy:

  • Problem: With aging systems, new evolving development tools, and hosting options, the evolution of cloud and serverless platforms maintaining the current system gets extremely painful with the addition of new features and functionalities. Completely replacing a system can be a huge task, for which gradual migration needs to be done such that the old system is still handled for the part that hasn't been migrated yet. This pattern solves this very problem.
  • Solution: The strangler solution resembles a vine that strangles a tree that it's wrapped over. Over time, the migrated application strangles the original application until you can shut off the monolithic application. Thus, the overall process is as follows:
  • Reconstruct: Construct a new application or site (in serverless or AWS cloud-based on modern principles). Incrementally reconstruct the functionalities in an agile manner.
  • Coexist: Leave the legacy application as it is. Introduce a facade that eventually acts as a proxy and decides where to route the request based on the current migration status. This facade can be introduced at web server level or programming level based on various parameters such as IP address, user agent, or cookies.
  • Terminate: Redirect everything to the modern migrated application and loosen off all the ties with the legacy application.

A sample gist of .htaccess that acts as a facade can be found at this link: https://gist.github.com/parthghiya/a6935f65a262b1d4d0c8ac24149ce61d.

The solution instructs us to create a facade or a proxy that has the ability to intercept the requests that are going to the backend legacy system. The facade or proxy then decides whether to route it to the legacy application or the new microservices. This is an incremental process, wherein both the systems can coexist. The end users won't even know when the migration process is complete. It gives the added advantage that if the adopted microservice approach doesn't work, there is a very simple way to change it.

  • Take care of: The following points need to be taken care of for effectively applying the strangulation pattern:
  • The facade or the proxy needs to be updated with the migration.
  • The facade or the proxy shouldn't be a single point of failure or bottleneck.
  • When the migration is complete, facade will evolve as the adapter for legacy applications.
  • The new code written should be such that it can easily be intercepted, so in future, we can replace it in future migrations.
  • When to use: The strangler application is extremely useful when it comes to replacing a legacy and monolithic application with microservices. The pattern is used in the following cases:
  • When you want to follow the test-driven on behavior-driven development, and run fast and comprehensive tests with the accessibility of code coverages and adapt CI/CD.
  • Your application can be contained bounded contexts within which a model applies in the region. As an example, in a shopping cart application, the product module would be one context.
  • When not to use: This pattern may not be applicable in the following scenarios:
  • When you are not able to intercept the user agent request, or you are not able to introduce a facade in your architecture.
  • When you think of doing a page by page migration at a time or you are thinking of doing it all at once.
  • When your application is more frontend-driven; that's where you have to entirely change and rework the interacting framework based on the way the frontend is interacting with services, as you don't want to expose the various ways the user agent is interacting with services.