Skip to content

API Gateway Routing — Path-Based, Header-Based, and Weight-Based Strategies

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about API Gateway Routing. We cover key concepts, practical examples, and best practices to help you master this topic.

Routing is the process of matching an incoming request to the correct backend service based on characteristics like the URL path, HTTP method, headers, or query parameters so the right service handles each request.

What You'll Learn

  • Path-based routing: the most common Strategy
  • Header-based routing for A/B testing and multi-version support
  • Weighted routing for gradual rollouts

Why It Matters

Without intelligent routing, every backend service would need to run its own front-end server, duplicating certificates, Rate Limiting, and logging. Centralized routing in the gateway simplifies operations and enables powerful traffic management strategies.

Real-World Use

Durga Antivirus Pro runs three versions of its scan API simultaneously. The gateway routes v1 requests to the legacy service, v2 requests to the current service, and a small percentage of requests with header X-Canary: true to a new Canary Deployment for testing.

flowchart LR
    Request["Incoming Request"] --> Router["Gateway Router"]
    Router -->|"/users/*"| US["User Service"]
    Router -->|"/orders/*"| OS["Order Service"]
    Router -->|"X-Version: v2"| V2["v2 Canary"]
    Router -->|"weight: 10%"| Canary["Canary Deploy"]
    style Router fill:#dbeafe,stroke:#2563eb

Path-Based Routing

The gateway matches the request URL path against predefined patterns. /users/* goes to the user service, /orders/* to the order service. This is the most common and simplest routing strategy.

from flask import Flask, request
import requests

app = Flask(__name__)

BACKEND_SERVICES = {
    "user": "http://user-service:8080",
    "order": "http://order-service:8080",
    "product": "http://product-service:8080"
}

PATH_MAP = {
    "/users": "user",
    "/orders": "order",
    "/products": "product"
}

@app.route("/<path:path>")
def route_request(path):
    prefix = "/" + path.split("/")[0]
    service_key = PATH_MAP.get(prefix)
    if not service_key:
        return {"error": "Unknown route"}, 404
    backend = BACKEND_SERVICES[service_key]
    backend_url = f"{backend}/{path}"
    resp = requests.request(
        method=request.method,
        url=backend_url,
        params=request.args,
        data=request.get_data(),
        headers=request.headers
    )
    return (resp.content, resp.status_code, resp.headers.items())

Header-Based Routing

Header-based routing examines HTTP headers to determine the destination. This is useful for A/B testing, versioning, and tenant isolation.

@app.route("/<path:path>")
def route_with_header(path):
    version = request.headers.get("X-API-Version", "v1")
    if version == "v2":
        backend = "http://user-service-v2:8080"
    else:
        backend = "http://user-service-v1:8080"
    resp = requests.get(f"{backend}/{path}")
    return resp.content, resp.status_code

Weighted Routing (Canary Deployments)

Weighted routing sends a percentage of traffic to a new version while the majority goes to the stable version.

import random

@app.route("/api/scan")
def scan_route():
    canary_percent = 10
    if random.randint(1, 100) <= canary_percent:
        backend = "http://scan-service-canary:8080"
        print("Routing to canary")
    else:
        backend = "http://scan-service-stable:8080"
    resp = requests.get(f"{backend}/scan", params=request.args)
    return resp.content, resp.status_code

Expected behavior: 10% of requests hit the canary deployment, allowing developers to validate changes before a full rollout.

Common Mistakes

1. Overlapping Route Patterns

A route /users/:id conflicts with /users/search if the router matches greedily. Define specific routes before parameterized ones.

2. Hardcoding Backend URLs

Backend services move, scale up, or get replaced. Use service discovery or environment variables for backend addresses.

3. Ignoring HTTP Method in Routing

Routing /users/42 with GET should fetch data, but DELETE should delete. Match on method as well as path, or delegate method handling to the backend.

4. Not Handling Trailing Slashes

Routes /users and /users/ may be treated differently. Normalize paths before matching to avoid unexpected 404 errors.

5. Forgetting Route Order

Most routers use first-match wins. If a catch-all pattern comes before specific routes, specific routes will never be reached.

Practice Questions

  1. What is the difference between path-based and header-based routing?
  2. How can weighted routing help with canary deployments?
  3. Why should specific routes be listed before parameterized routes?
  4. What happens if two route patterns match the same request?
  5. How can you avoid hardcoding backend URLs in routing configuration?

Answers:

  1. Path-based routing uses the URL path to determine the backend; header-based routing uses HTTP header values for more dynamic decisions.
  2. Weighted routing sends a small percentage of traffic to a new version, allowing real-world validation without risking all users.
  3. Parameterized routes with wildcard segments will match everything, so specific routes must be checked first.
  4. The router typically uses first-match wins. Ensure patterns are ordered from most to least specific.
  5. Use environment variables, a configuration file, or service discovery tools like Consul to resolve backend addresses dynamically.

Challenge: Design a routing table for an e-commerce gateway with services for products, cart, checkout, payments, and shipping. Include a canary route for the payment service.

FAQ

Can a gateway route based on query parameters?

: Yes. The gateway can inspect ?country=us or ?source=mobile and route to the appropriate backend or version.

Does routing add significant request overhead?

: Route table lookups take microseconds, especially with prefix-trie or radix tree implementations.

How do gateways handle routing for gRPC services?

: They inspect the gRPC service/method name from the path or :authority header and route accordingly.

Can routing be changed without restarting the gateway?

: Yes. Dynamic routing reloads configuration from a file, database, or service discovery without downtime.

What is the best data structure for route matching?

: A radix tree or compressed trie provides O(k) lookup time where k is the path length, ideal for high-performance routing.

Mini Project

Create a Python gateway that routes requests based on path prefix AND a custom header X-Deploy-Version. If the header is staging, route to staging backends; otherwise use production backends. Support routes for /users, /orders, and /inventory.

What's Next

Continue with Load Balancing in Gateway to distribute requests across service instances, or explore Rate Limiting in Gateways to protect backends from traffic spikes.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro