Routes
Routes in Gateway API define how traffic is routed from Gateways to backend Services. The most common route type is HTTPRoute, which provides rich HTTP routing capabilities including path matching, header matching, traffic splitting, and request/response modification. Understanding Routes is essential for effectively using Gateway API.
What are Routes?
Routes are resources that attach to Gateways and define routing rules. They specify:
- What traffic to match - Paths, headers, hostnames
- Where to route - Backend Services
- How to modify - Request/response transformations
HTTPRoute Structure
An HTTPRoute consists of:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-route
spec:
parentRefs: # Which Gateway to attach to
- name: example-gateway
hostnames: # Hostnames to match
- example.com
rules: # Routing rules
- matches: # Conditions to match
- path:
type: PathPrefix
value: /api
backendRefs: # Where to route
- name: api-service
port: 80
Basic HTTPRoute
Here’s a simple HTTPRoute:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: basic-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: web-service
port: 80
This routes all traffic from the Gateway to web-service.
Path Matching
HTTPRoute supports multiple path matching types:
PathPrefix
Matches path and all subpaths:
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 80
Matches: /api, /api/, /api/users, /api/v1/users
Exact
Matches only the exact path:
rules:
- matches:
- path:
type: Exact
value: /api
backendRefs:
- name: api-service
port: 80
Matches: /api only (not /api/ or /api/users)
RegularExpression
Matches using regular expressions:
rules:
- matches:
- path:
type: RegularExpression
value: "^/api/v[0-9]+"
backendRefs:
- name: api-service
port: 80
Matches: /api/v1, /api/v2, /api/v10, etc.
Hostname Matching
Match requests based on HTTP hostname:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: hostname-route
spec:
parentRefs:
- name: example-gateway
hostnames:
- api.example.com
- www.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: web-service
port: 80
Only requests to api.example.com or www.example.com match this route.
Header Matching
Match requests based on HTTP headers:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: header-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- headers:
- name: version
value: v2
- name: X-Custom-Header
value: "custom-value"
backendRefs:
- name: api-v2-service
port: 80
This routes requests with version: v2 header to api-v2-service.
Query Parameter Matching
Match requests based on query parameters:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: query-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- queryParams:
- name: version
value: v2
backendRefs:
- name: api-v2-service
port: 80
Routes requests with ?version=v2 to api-v2-service.
Method Matching
Match requests based on HTTP method:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: method-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- method: GET
backendRefs:
- name: read-service
port: 80
- matches:
- method: POST
backendRefs:
- name: write-service
port: 80
Traffic Splitting
Split traffic across multiple backends:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: split-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-v1-service
port: 80
weight: 90
- name: api-v2-service
port: 80
weight: 10
90% of traffic goes to api-v1-service, 10% to api-v2-service.
Request Filters
Modify requests before routing:
RequestHeaderModifier
Add, set, or remove headers:
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Forwarded-For
value: "true"
set:
- name: X-Custom-Header
value: "custom"
remove:
- "X-Old-Header"
backendRefs:
- name: api-service
port: 80
URLRewrite
Rewrite URLs:
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /v1
backendRefs:
- name: api-service
port: 80
Rewrites /api/users to /v1/users before forwarding.
RequestRedirect
Redirect requests:
rules:
- matches:
- path:
type: PathPrefix
value: /old
filters:
- type: RequestRedirect
requestRedirect:
statusCode: 301
hostname: example.com
path:
type: ReplacePrefixMatch
replacePrefixMatch: /new
backendRefs:
- name: api-service
port: 80
Redirects /old/* to example.com/new/* with 301 status.
Response Filters
Modify responses (if supported by controller):
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: X-Custom-Response
value: "true"
backendRefs:
- name: api-service
port: 80
Multiple Rules
HTTPRoute can have multiple rules, evaluated in order:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: multi-rule-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /api/v2
backendRefs:
- name: api-v2-service
port: 80
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-v1-service
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: web-service
port: 80
Rules are evaluated in order, first match wins.
Cross-Namespace Routing
HTTPRoute can reference Services in other namespaces:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: cross-ns-route
namespace: frontend
spec:
parentRefs:
- name: example-gateway
namespace: infrastructure
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
namespace: backend
port: 80
Note: Cross-namespace references may require additional RBAC permissions.
Complete Example
Here’s a complete HTTPRoute with multiple features:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: complete-route
namespace: production
spec:
parentRefs:
- name: shared-gateway
hostnames:
- api.example.com
- www.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /api/v2
headers:
- name: version
value: v2
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-API-Version
value: "2.0"
backendRefs:
- name: api-v2-service
port: 80
weight: 100
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-v1-service
port: 80
weight: 90
- name: api-v2-service
port: 80
weight: 10
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: web-service
port: 80
Best Practices
- Order rules carefully - More specific rules before general ones
- Use descriptive names - Route names should indicate purpose
- Document complex rules - Comment complex matching logic
- Test thoroughly - Verify all rules match as expected
- Use filters wisely - Filters add complexity, use when needed
- Monitor route status - Check HTTPRoute status for issues
- Plan traffic splitting - Carefully plan weight distributions
- Use namespaces - Organize routes by namespace
- Leverage hostnames - Use hostname matching for multi-tenant scenarios
- Keep it simple - Start simple, add complexity gradually
Troubleshooting
Route Not Attaching
- Check parent reference: Verify Gateway name is correct
- Check namespace: Ensure Gateway is accessible from route namespace
- Verify Gateway status: Ensure Gateway is ready
- Review route status:
kubectl get httproute <name> -o yaml - Check controller logs: Review Gateway API controller logs
Traffic Not Routing
- Verify matches: Ensure match conditions are correct
- Check backend Services: Verify Services exist and have Endpoints
- Test Services directly: Bypass Gateway to test Services
- Review rule order: Ensure rules are ordered correctly
- Check route status: Look for acceptance/conditions in status
Filters Not Working
- Verify controller support: Ensure controller supports used filters
- Check filter syntax: Verify filter configuration is correct
- Review controller docs: Check controller-specific filter requirements
- Test without filters: Verify routing works without filters first
- Check controller logs: Look for filter processing errors
See Also
- Gateway API Overview - Introduction to Gateway API
- Ingress vs Gateway API - Comparison guide
- Services - Backend Services that Routes reference
- Ingress - Traditional HTTP routing alternative