Skip to content

Routes and matching

A route decides which service handles an HTTP request. Every field that contains a matcher must match.

Field What it matches
hosts Exact hostnames, *.example.com wildcards, or *
paths Path prefixes or regular expressions that start with ~
methods HTTP methods such as GET or POST
headers An exact header value, or "*" when the header only needs to exist
priority Which matching route wins. Higher values win.

An empty list matches any value for that field.

Hostname matching ignores case, an incoming port, and a trailing DNS dot.

  • api.example.com matches only that hostname.
  • *.example.com matches api.example.com and a.b.example.com.
  • *.example.com does not match example.com.
  • * matches every hostname.

A path prefix stops at a segment boundary:

Pattern /api /api/users /apixyz
/api match match no match

/ matches every path.

Start a path with ~ to use a regular expression:

{
"paths": ["~/users/[0-9]+"]
}

Raahi always starts the match at the beginning of the request path. Add $ when the expression must match the complete path.

When several routes match, Raahi chooses them in this order:

  1. Highest priority
  2. Longest matched path
  3. Lowest route ID

The last rule makes ties deterministic.

Set strip_path to remove the matched path before proxying. On a route with /api, a request to /api/users reaches the upstream as /users.

Set preserve_host to forward the client’s original Host header. Otherwise Raahi sends the target hostname.

Raahi adds X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto.

A route normally sends requests to service_id. If splits contains entries, Raahi uses their weights instead:

{
"service_id": 12,
"splits": [
{ "service_id": 12, "weight": 90 },
{ "service_id": 18, "weight": 10 }
]
}

Use the router tester to select a route without contacting its upstream.