Routing
Nylon routes requests by combining host, header, and path rules with optional rewrites and middleware. This guide walks through the most common scenarios—from the basics to more advanced matching—so you can design clear, maintainable route layouts.
Quick Start
routes:
- route:
type: host
value: api.example.com
name: api
paths:
- path: /v1/{*path}
service:
name: api-v1
- path: /{*path}
service:
name: fallback- Choose a matcher (
hostorheader) for the route. - Name the route so you can refer to it in logs and dashboards.
- Describe one or more
pathsand map each to a backend service. - Optionally attach middleware, TLS, or rewrites per path.
Building Blocks
- Route matcher (
route.type,route.value): Determines when the route is eligible. You can list multiple hosts separated by|. - Path entry (
paths[].path): Checked in order to match the request path and HTTP method. - Service block (
service): Points to the upstream service and optional rewrite target. - Middleware (
middlewareormiddleware_groups): Attach reusable filters or plugin handlers.
Matching Strategies
Host-based routing
routes:
- route:
type: host
value: api.example.com|api.internal
paths:
- path: /{*path}
service:
name: api-serviceUse host matching to separate traffic by domain or subdomain. Wildcard * catches any host that did not match previously defined routes.
Header-based routing
Enable multi-tenant or environment-specific configurations by inspecting a request header. Set a header_selector at the top of your config, then bind each header value to a route.
header_selector: x-nylon-environment
routes:
- route:
type: header
value: staging
name: staging-app
paths:
- path: /{*path}
service:
name: staging-backendMethod filtering
Restrict a path to specific HTTP methods. Nylon accepts GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT, and TRACE.
paths:
- path: /api/users
methods:
- GET
- POST
service:
name: user-servicePath Patterns
| Pattern | Matches | Notes |
|---|---|---|
/status | Exact /status | Fastest match |
/users/{id} | Any single segment (/users/42) | Captured as params["id"] |
/assets/{*path} | All trailing segments | Catch-all; lowest priority |
/{*path} | Everything | Use as a final fallback |
Extracted parameters are available inside plugins:
phase.RequestFilter(func(ctx *sdk.PhaseRequestFilter) {
if userID, ok := ctx.Request().Params()["id"]; ok {
ctx.Logger().Info("routing user", "id", userID)
}
ctx.Next()
})Multiple paths per route
Organize related paths under the same route and share middleware when needed.
routes:
- route:
type: host
value: app.example.com
paths:
- path: /api/{*path}
service:
name: api
middleware:
- plugin: auth
entry: check
- path: /static/{*path}
service:
name: cdn
- path:
- /
- /{*path}
service:
name: webPath Rewrites
Rewrites adjust the upstream request path without changing the path matched by the client.
paths:
- path: /old-api/{*path}
service:
name: new-api
rewrite: /v2
- path: /api/v1/{*path}
service:
name: api-v1
rewrite: /- When the route matches
/old-api/users, Nylon proxies to/v2/users. - Use
/to strip a prefix entirely.
How Matching Order Works
Nylon uses matchit v0.8 to score routes:
- Exact segments (
/health) take priority. - Named parameters (
/{user}) run next. - Catch-all parameters (
/{*path}) match last.
paths:
- path: /api/health # 1 — exact
- path: /api/{resource} # 2 — named parameter
- path: /{*path} # 3 — catch-all fallback
service:
name: fallbackOrder still matters when two paths have the same precedence—define the most specific entries first.
Dynamic Routing & Segmentation
Combine host, header, and method rules to isolate workloads or tenants.
header_selector: x-nylon-proxy
routes:
- route:
type: header
value: tenant-a
name: tenant-a
paths:
- path: /admin/{*path}
service:
name: admin
methods:
- GET
- POST
middleware:
- plugin: auth
entry: admin
- path: /{*path}
service:
name: appRequests with x-nylon-proxy: tenant-a use the above layout, while other values can map to different services or environments.
End-to-end Example
header_selector: x-nylon-proxy
routes:
- route:
type: host
value: api.example.com
name: api
tls:
enabled: true
middleware:
- group: observability
paths:
- path: /public/{*path}
service:
name: public-api
- path: /v1/{*path}
service:
name: api-v1
middleware:
- plugin: auth
entry: jwt
- path: /admin/{*path}
methods:
- GET
- POST
service:
name: admin-api
- route:
type: host
value: static.example.com
name: static
paths:
- path:
- /
- /{*path}
service:
name: cdn
- route:
type: host
value: "*"
name: default
paths:
- path:
- /
- /{*path}
service:
name: default-backendBest Practices
- Lead with specificity: Put the narrowest path first and reserve catch-all entries for the bottom.
- Group shared behavior: Use middleware groups to apply authentication, rate limiting, or logging policies consistently.
- Segment by domain: Split public, admin, API, and static traffic into separate routes for clarity.
- Prefer parameters over wildcards: Named segments make logs and plugins easier to reason about.
- Document rewrites: Include comments or naming conventions so teams understand why a rewrite exists.
Next Steps
- Configuration for every available field.
- Middleware to attach logic to routes.
- Examples for complete proxy configurations.