Incrementally replace a legacy system behind a routing façade, migrating one piece at a time instead of a risky big-bang rewrite.
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.
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.
Only `/orders/*` has been migrated so far; every other path still falls through to the legacy system unchanged.
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