Using Traefik Rewrite Middleware to Safely Migrate Legacy API Endpoints
Learn how Traefik’s Rewrite middleware can transparently map legacy API paths to new versions, reducing code churn and enabling safe, observable migrations.
22 Aug 2026, 02:49 UTC

The problem: keeping old URLs alive while moving to a new API
Many teams need to retire an old URL prefix (e.g., /old/api/v1/) after releasing a newer version (/new/api/v2/). Changing the application code to support both paths can introduce bugs, require redeploys, and make rollback cumbersome. Doing the redirect at the client level forces users to update bookmarks or scripts, which is often undesirable.
Thesis: Traefik’s Rewrite middleware lets you translate URLs at the edge without touching backend code
By placing the Rewrite middleware in front of a router, Traefik can internally map an incoming request that matches a legacy pattern to the new backend path while preserving the original URL in the client’s view. This provides a transparent migration path, allows gradual rollout, and can be removed or adjusted with minimal risk.
How the Rewrite middleware works
The middleware evaluates each request against a configured regular expression. If the expression matches, captured groups can be reused in a replacement string to construct the new internal path. Query strings are preserved by default, and you can optionally set a redirect status code if you want the client to see a different URL. Importantly, the middleware only changes the request that Traefik forwards to the service; the client’s original request line remains unchanged unless you also add a redirect middleware.
Worked example: mapping /old/api/v1/ to /new/api/v2/
Assume a Traefik instance configured via static file traefik.yml and a Docker service named api-new listening on port 8080.
# traefik.yml (static configuration)
http:
middlewares:
old-to-new:
rewriteRegex:
regex: ^/old/api/v1/(.*)
replacement: /new/api/v2/$1
routers:
legacy-api:
rule: Host(`legacy.example.com`) && PathPrefix(`/old/api/v1/`)
service: api-new
middlewares:
- old-to-new
services:
api-new:
loadBalancer:
servers:
- url: http://api-new:8080
When a client requests http://legacy.example.com/old/api/v1/users:
- Traefik matches the
legacy-apirouter. - The
old-to-newmiddleware sees the path matches^/old/api/v1/(.*), capturesusers, and rewrites the internal path to/new/api/v2/users. - The request is forwarded to the
api-newservice, which processes/new/api/v2/usersand returns the response. - The client receives the response as if the original URL had been served, with no visible change in the address bar or response headers (unless a redirect middleware is added).
Trade‑offs and limitations
- Latency: Each request incurs a small CPU cost for regex evaluation. For very high‑traffic workloads, benchmark the impact.
- Debugging complexity: Because the internal path differs from what the client sees, you need to check Traefik logs or the dashboard to confirm the rewrite occurred.
- Pattern safety: An unanchored or overly permissive regex could rewrite unintended paths. Always anchor expressions (e.g., start with
^) and test against a representative sample of real URLs. - Client‑side redirects: If you need the browser to display the new URL, combine Rewrite with a RedirectRegex middleware or return a 301/302 from the backend.
Actionable steps: deploy, verify, and roll back
- Deploy in staging: Add the middleware configuration to your staging Traefik instance and reload.
- Verify with curl:
Expect acurl -I http://legacy-staging.example.com/old/api/v1/users200 OK(or whatever your backend returns) and confirm that the response body matches the new endpoint.
The request line shown by curl should still containcurl -v http://legacy-staging.example.com/old/api/v1/users 2>&1 | grep -E "^(>|<)"/old/api/v1/users, while the response payload originates from the new backend. - Observe hit counters: Access the Traefik API (
http://traefik:8080/api/http/middlewares/old-to-new) and ensure thehitCountincrements after each test request. - Promote to production: After successful staging validation, apply the same configuration to production, enable alerts on error rates or latency spikes, and monitor for any unexpected rewrite matches.
- Rollback (if needed): Since the middleware only changes routing, you can revert by removing the
old-to-newmiddleware from the router or deleting the router entirely, then reloading Traefik. This restores the original behavior without touching backend code.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.