Cloud · Gateway & Routing · DWG NO. 036

Strangler Fig

Incrementally replace a legacy system behind a routing façade, migrating one piece at a time instead of a risky big-bang rewrite.

TypeGateway/Routing
ScopeWhole system migration
ComplexityMedium–High
Common inLegacy modernization, monolith-to-microservices migrations

A full rewrite is a multi-year bet with no working software until it ships

Rewriting a large legacy system from scratch means running both the old and new systems' full feature sets in parallel for a long stretch, with a risky cutover at the end — and the business logic buried in the old system tends to be poorly documented, so scope creeps as "just one more thing" is discovered.

A façade routes traffic, piece by piece, to the new system

Named after a fig vine that grows around a host tree and gradually replaces it: a routing façade sits in front of the legacy system. New functionality is built and deployed behind the façade, one route at a time; the façade sends matching requests to the new service and everything else to the legacy system — until nothing routes to the legacy system anymore.

Façade(router)/orders/*everything elseNew Orders ServiceLegacy Monolith

A façade routing incrementally to a new service

Only `/orders/*` has been migrated so far; every other path still falls through to the legacy system unchanged.

strangler-facade.js
const legacyMonolith = {
  handle: (path) => `legacy: handled ${path}`,
};

const newOrdersService = {
  handle: (path) => `new-orders-service: handled ${path}`,
};

function facade(path) {
  if (path.startsWith("/orders")) {
    return newOrdersService.handle(path); // migrated route
  }
  return legacyMonolith.handle(path); // not migrated yet
}

console.log(facade("/orders/42"));   // routed to the new service
console.log(facade("/inventory/9")); // still routed to legacy

Trade-offs