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
graph TB A[HTTP Request] --> B[Gateway] B --> C[HTTPRoute Evaluates Rules] C --> D{Matches Rule?} D -->|Yes| E[Apply Filters] D -->|No| F[Default or 404] E --> G[Route to Backend Service] style B fill:#e8f5e9 style C fill:#fff4e1 style G fill:#fff4e1

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.

graph TB A[Traffic: /api] --> B[HTTPRoute] B --> C[90% to v1] B --> D[10% to v2] C --> E[API v1 Service] D --> F[API v2 Service] style B fill:#e8f5e9 style E fill:#fff4e1 style F fill:#fff4e1

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

  1. Order rules carefully - More specific rules before general ones
  2. Use descriptive names - Route names should indicate purpose
  3. Document complex rules - Comment complex matching logic
  4. Test thoroughly - Verify all rules match as expected
  5. Use filters wisely - Filters add complexity, use when needed
  6. Monitor route status - Check HTTPRoute status for issues
  7. Plan traffic splitting - Carefully plan weight distributions
  8. Use namespaces - Organize routes by namespace
  9. Leverage hostnames - Use hostname matching for multi-tenant scenarios
  10. Keep it simple - Start simple, add complexity gradually

Troubleshooting

Route Not Attaching

  1. Check parent reference: Verify Gateway name is correct
  2. Check namespace: Ensure Gateway is accessible from route namespace
  3. Verify Gateway status: Ensure Gateway is ready
  4. Review route status: kubectl get httproute <name> -o yaml
  5. Check controller logs: Review Gateway API controller logs

Traffic Not Routing

  1. Verify matches: Ensure match conditions are correct
  2. Check backend Services: Verify Services exist and have Endpoints
  3. Test Services directly: Bypass Gateway to test Services
  4. Review rule order: Ensure rules are ordered correctly
  5. Check route status: Look for acceptance/conditions in status

Filters Not Working

  1. Verify controller support: Ensure controller supports used filters
  2. Check filter syntax: Verify filter configuration is correct
  3. Review controller docs: Check controller-specific filter requirements
  4. Test without filters: Verify routing works without filters first
  5. Check controller logs: Look for filter processing errors

See Also