Modernizing a legacy application can be challenging when the existing system supports critical business operations. Replacing the entire application at once introduces risks, including downtime, data inconsistencies, and unexpected failures.
The strangler fig migration pattern offers a gradual alternative. strangler fig migration routing rules for legacy endpoints Instead of replacing the legacy application in one step, organizations introduce new services incrementally while the old system continues operating. A routing layer directs requests to the appropriate implementation, allowing the new architecture to grow over time.
However, successful migration depends on carefully designed routing rules for legacy endpoints.
The strangler fig pattern is an application modernization approach in which new functionality gradually replaces parts of an existing system.
For example, a company may have a legacy application that handles customer accounts, orders, payments, and reporting. The development team might migrate the customer API first, followed by orders and reporting, while leaving payment processing in the original system until it is ready.
A reverse proxy, API gateway, or application-level routing component determines which system handles each request.
The old application remains available for functionality that has not yet migrated.
Before defining routing rules, create an inventory of the legacy application’s endpoints.
Record details such as:
For example:
| Endpoint | Purpose | Migration status |
|---|---|---|
| GET /api/customers | Retrieve customer records | Migrated |
| POST /api/orders | Create an order | Legacy |
| GET /api/reports | Generate reports | Legacy |
This inventory provides a clear picture of the current system and helps teams decide which endpoints should move first.
Routing rules should identify exactly which requests go to the new service and which remain in the legacy application.
A basic routing policy could be:
The rules should consider HTTP methods, path patterns, authentication context, and any required request attributes.
For example, migrating GET /api/customers does not automatically mean that POST /api/customers should also use the new service. The two operations may have different implementation and data dependencies.
Specific routes should take precedence over broader wildcard routes to prevent accidental misrouting.
An API gateway or reverse proxy can centralize routing decisions.
For example, a gateway might forward requests for /api/customers/* to the new customer service while directing /api/orders/* to the legacy application.
The routing layer should preserve required headers, authentication context, request methods, query parameters, and response semantics.
It should also apply appropriate timeouts, request-size limits, rate limits, and observability policies.
Keep routing configuration separate from business logic wherever practical. This makes it easier to modify migration rules without introducing unnecessary changes to application code.
Feature flags allow teams to enable or disable new implementations without deploying a completely new application version.
Initially, a migrated endpoint can be enabled for internal users or a small group of customers. After successful validation, the team can expand access gradually.
A rollout might follow these stages:
Feature flags should have clear ownership, documented conditions, and removal dates. Permanent migration flags create unnecessary complexity and make routing behavior harder to understand.
A new service may experience timeouts, errors, or unexpected response differences. Teams must decide what happens when the new implementation fails.
For read-only operations, fallback to the legacy system may be possible if both systems provide equivalent results and consistent data.
For write operations, automatic fallback is more dangerous. If the new service processes a request but the response is lost, sending the same request to the legacy system may create duplicate orders or payments.
Use idempotency keys, explicit operation tracking, and carefully defined failure policies. Do not automatically retry or redirect writes unless the operation is safe to repeat.
Rollback procedures should be tested before increasing production traffic.
Routing requests to different implementations becomes complicated when both systems access overlapping data.
Before migration, define which system owns each data entity and which system is allowed to write to it.
Avoid allowing both applications to independently update the same records without a consistency strategy.
Depending on the architecture, teams may use APIs, change-data capture, event-driven synchronization, or temporary compatibility layers.
Every migration stage should document data ownership, synchronization delays, and recovery procedures.
Monitoring helps identify problems before a migration affects a large number of users.
Track request volume by route, destination service, response status, latency, timeout frequency, and fallback usage.
Compare error rates and response behavior between the new and legacy implementations. Logs should include a correlation ID so that requests can be traced across gateways and services.
Alerts should identify unusual traffic patterns, repeated routing failures, and unexpected increases in legacy usage.
An endpoint should not be removed simply because the new implementation is available.
Confirm that consumers have migrated, production traffic has stopped, integrations have been updated, and rollback is no longer required.
Document the retirement date and remove obsolete routing rules, feature flags, and compatibility code.
Strangler fig migration enables organizations to modernize applications incrementally without replacing the entire system at once. Reliable routing requires an endpoint inventory, explicit route matching, controlled feature flags, safe rollback behavior, clear data ownership, and continuous monitoring.
By treating routing rules as versioned architectural policies rather than temporary configuration, development teams can reduce migration risks and move toward a modern architecture with greater confidence.