HTTP routing
Routes are evaluated top to bottom. The first match wins, so put constrained routes before a catch-all.
Match and route
routes:
- name: api-v1
match:
host: api.example.com
path_prefix: /v1
methods: [GET, POST]
headers: { x-tenant: acme }
query: { version: stable }
upstream: api
rewrite:
host: api.internal
strip_prefix: /v1
add_prefix: /public
encode: true
max_body: 1048576
- name: health-response
match: { host: api.example.com, path_prefix: /edge-health }
respond:
status: 200
body: ok
headers: { content-type: text/plain }
- name: fallback
upstream: web A match may combine an exact host, path_prefix, allowed methods, exact required headers, and decoded query key/value pairs. Empty match fields mean “any.” Host matching does not include the port. Each configured repeated query pair must be present; a request may have additional query values.
Set exactly one of upstream or respond. A static response does not contact a backend. max_body is a byte limit; larger request bodies receive 413. encode: true enables route response compression.
Regular expressions
routes:
- name: tenant-assets
match:
host_regex: '^assets\.example\.com$'
path_regex: '^/files/[a-z0-9/_-]+\.js$'
upstream: assets Use either host or host_regex, and either path_prefix or path_regex; the pairs are mutually exclusive. Host regular expressions are case-insensitive. Path regular expressions see the URI path without its query string and are compiled during configuration validation.
Rewrites
rewrite.host changes the Host header sent upstream. strip_prefix and add_prefix change the upstream path. Keep the public match and upstream path contract explicit; test both a request that should match and a neighboring path that should not.
Response cache
routes:
- name: catalog
match: { host: shop.example.com, path_prefix: /catalog }
upstream: catalog
cache: { ttl: 30s, max_body: 524288 } Cache is per-route and applies only to cacheable GET responses. The server-wide server.cache_max_entries bounds the shared LRU; 0 disables it. Do not enable it for personalized or authorization-dependent responses unless the application’s response semantics make that safe.