Lesson 6 / 26

Routing by Path and Header

Send requests to different backends by URL path or by a request header.

Rules, evaluated in order

A gateway chooses a backend by matching host (api.example.com), path prefix (/orders/), method and headers. Path routing is the common case: /orders/* goes to the orders service and /users/* to the users service. Header-based routing enables opt-in canaries and internal testing: a request with X-Canary: 1 is sent to the new version while everyone else stays on stable. Be careful that clients cannot forge internal headers: strip or overwrite them at the edge. Order and specificity matter, so test the most specific rule wins.

The routing rule

A map picks the upstream pool from the X-Canary header, and proxy_pass uses the result. Excerpt of the gateway config.

map $http_x_canary $orders_pool { default orders_stable; "1" orders_canary; }

upstream orders_stable { server orders-v1:8080; }
upstream orders_canary { server orders-v2:8080; }

location /pick/ { proxy_pass http://$orders_pool/; }

Header routing, run

I ran this against a real nginx 1.27 gateway in Docker, with small Node.js services as upstreams (full setup in the case study). Without the header the request is served by v1; with X-Canary: 1 it reaches v2.

# client side (see the test client): two calls to /pick/x
GET /pick/x                      -> version
GET /pick/x   X-Canary: 1        -> version

Output:

v1 v2

Do not trust client-supplied routing headers

If a public client can send X-Canary: 1 or X-User-Id, they can reach unreleased code or impersonate users. Accept such headers only from trusted callers, or set them yourself after authentication.

Quick check: What is a risk of header-based routing?

  • It removes the need for auth
  • Headers cannot be read
  • It makes TLS impossible
  • Public clients may forge the header to reach unintended backends
Answer

Public clients may forge the header to reach unintended backends — Treat routing headers as untrusted unless the edge sets or validates them.