Skip to main content

Advanced Routing: Headers, Query Parameters, and Methods

Intermediate
  • Header Matching
  • Nginx Ingress - Header Annotations
  • Gateway API - Header Matching
  • +30 more sections...

Advanced Routing: Headers, Query Parameters, and Methods

Gateway API provides powerful matching capabilities beyond just paths and hostnames. This guide covers header matching, query parameter matching, and HTTP method matching, comparing them to Nginx Ingress equivalents.

Header Matching

Header & Query Parameter Matching

How Gateway API routes traffic based on HTTP headers and query parameters

Request Flow

Incoming HTTP Request

HTTPRoute Matching Rules

Header Match
X-Environment: staging
Query Parameter Match
version=v2
No Match
Request doesn't match any rules
Match Found
Request routed to matching backend service
No Match
Request returns 404 or default route

Match Types

Exact Match

Header value must match exactly

X-Env: staging

Prefix Match

Header value starts with prefix

X-Env: staging-*

Regular Expression

Complex pattern matching

X-Env: /^staging-.*$/

Common Use Cases

  • A/B testing based on user headers
  • Environment routing (staging, production)
  • Feature flags via headers
  • API versioning via query parameters

vs. Ingress: Gateway API has native header/query matching. Ingress requires custom Nginx configuration snippets or annotations.

Header matching allows you to route traffic based on HTTP headers. This is useful for A/B testing, environment routing, and feature flags.

Nginx Ingress - Header Annotations

Nginx Ingress requires annotations for header-based routing:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: header-ingress
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |
      if ($http_x_environment = "staging") {
        return 307 $scheme://staging.example.com$request_uri;
      }
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: default-service
                port:
                  number: 80

This requires custom Nginx configuration snippets!

Gateway API - Header Matching

Gateway API has native header matching:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: header-route
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - example.com
  rules:
    - matches:
        - headers:
            - name: X-Environment
              value: staging
      backendRefs:
        - name: staging-service
          port: 80
    - matches:
        - headers:
            - name: X-Environment
              value: production
      backendRefs:
        - name: production-service
          port: 80
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: default-service
          port: 80

Header Match Types

Gateway API supports different header match types:

Exact Match (Default)

matches:
  - headers:
      - name: X-Environment
        value: staging

Matches when header value exactly equals "staging".

Regular Expression Match

matches:
  - headers:
      - name: X-Version
        type: RegularExpression
        value: "^v[0-9]+"

Matches when header value matches the regex pattern.

Multiple Headers

You can match on multiple headers (AND logic):

matches:
  - headers:
      - name: X-Environment
        value: staging
      - name: X-User-Type
        value: premium
    backendRefs:
      - name: premium-staging-service
        port: 80

This matches requests that have both headers with the specified values.

Multiple Header Matches (OR Logic)

To create OR logic, use multiple match blocks:

rules:
  - matches:
      - headers:
          - name: X-Environment
            value: staging
      - headers:
          - name: X-Environment
            value: development
    backendRefs:
      - name: non-prod-service
        port: 80

Query Parameter Matching

Query parameter matching allows routing based on URL query strings.

Nginx Ingress - Query Parameters

Nginx Ingress requires server snippets for query parameter matching:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: query-ingress
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |
      if ($arg_version = "v2") {
        return 307 $scheme://v2.example.com$request_uri;
      }

Gateway API - Query Parameter Matching

Gateway API has native query parameter matching:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: query-route
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - example.com
  rules:
    - matches:
        - queryParams:
            - name: version
              value: v2
      backendRefs:
        - name: v2-service
          port: 80
    - matches:
        - queryParams:
            - name: version
              value: v1
      backendRefs:
        - name: v1-service
          port: 80

Query Parameter Match Types

Exact Match

matches:
  - queryParams:
      - name: env
        value: staging

Matches ?env=staging.

Regular Expression Match

matches:
  - queryParams:
      - name: version
        type: RegularExpression
        value: "^v[0-9]+"

Matches ?version=v1, ?version=v2, etc.

HTTP Method Matching

HTTP method matching allows routing based on the HTTP verb (GET, POST, PUT, DELETE, etc.).

Nginx Ingress - Method Matching

Nginx Ingress requires server snippets:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: method-ingress
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |
      if ($request_method = "POST") {
        return 307 $scheme://api-write.example.com$request_uri;
      }

Gateway API - Method Matching

Gateway API has native method matching:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: method-route
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - example.com
  rules:
    - matches:
        - method: POST
          path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: write-service
          port: 80
    - matches:
        - method: GET
          path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: read-service
        port: 80

Supported HTTP Methods

  • GET
  • HEAD
  • POST
  • PUT
  • DELETE
  • CONNECT
  • OPTIONS
  • TRACE
  • PATCH

Combining Match Conditions

One of Gateway API's powerful features is combining multiple match conditions.

Single Match with Multiple Conditions (AND)

All conditions in a single matches entry must be true:

matches:
  - path:
      type: PathPrefix
      value: /api
    headers:
      - name: X-Environment
        value: staging
    method: POST
    queryParams:
      - name: version
        value: v2

This matches: POST /api/users?version=v2 with header X-Environment: staging.

Multiple Matches (OR)

Multiple matches entries create OR logic:

rules:
  - matches:
      - path:
          type: PathPrefix
          value: /api/v1
      - path:
          type: PathPrefix
          value: /api/v2
    backendRefs:
      - name: api-service
        port: 80

This matches either /api/v1 OR /api/v2.

Complete Examples

Example 1: Environment-Based Routing

Route traffic to different services based on environment header:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: environment-route
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - example.com
  rules:
    # Staging environment
    - matches:
        - headers:
            - name: X-Environment
              value: staging
      backendRefs:
        - name: staging-service
          port: 80
    # Production environment
    - matches:
        - headers:
            - name: X-Environment
              value: production
      backendRefs:
        - name: production-service
          port: 80
    # Default
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: default-service
          port: 80

Example 2: Feature Flag Routing

Route based on feature flag header:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: feature-flag-route
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - example.com
  rules:
    # New feature enabled
    - matches:
        - headers:
            - name: X-Feature-NewUI
              value: "true"
      backendRefs:
        - name: new-ui-service
          port: 80
    # Default
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: old-ui-service
          port: 80

Example 3: API Version via Query Parameter

Route based on API version in query string:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api-version-route
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - api.example.com
  rules:
    # Version 2
    - matches:
        - queryParams:
            - name: version
              value: v2
      backendRefs:
        - name: api-v2-service
          port: 80
    # Version 1 (default)
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: api-v1-service
          port: 80

Example 4: Read/Write Separation

Separate read and write traffic:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: read-write-route
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - api.example.com
  rules:
    # Write operations
    - matches:
        - method: POST
        - method: PUT
        - method: DELETE
        - method: PATCH
      backendRefs:
        - name: write-service
          port: 80
    # Read operations
    - matches:
        - method: GET
        - method: HEAD
      backendRefs:
        - name: read-service
          port: 80

Example 5: Complex Combined Matching

Combine path, header, method, and query parameters:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: complex-route
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - example.com
  rules:
    # Premium users, POST to /api, v2 version
    - matches:
        - path:
            type: PathPrefix
            value: /api
          headers:
            - name: X-User-Type
              value: premium
          method: POST
          queryParams:
            - name: version
              value: v2
      backendRefs:
        - name: premium-v2-write-service
          port: 80
    # Default API route
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: default-api-service
          port: 80

Comparison Table

FeatureNginx IngressGateway API
Header MatchingServer snippetsNative headers field
Query ParametersServer snippetsNative queryParams field
Method MatchingServer snippetsNative method field
Multiple ConditionsComplex snippetsNative combination
PortabilityNginx-specificStandard across implementations

Best Practices

  1. Use Headers for Environment Routing: Headers are great for A/B testing and environment separation
  2. Query Params for API Versioning: Query parameters work well for API version selection
  3. Method Matching for Read/Write Separation: Separate read and write operations
  4. Combine Conditions Carefully: Understand AND vs OR logic
  5. Order Matters: More specific matches should come first
  6. Default Fallback: Always include a default rule for unmatched requests

Common Use Cases

Use Case 1: Canary Deployment with Headers

rules:
  - matches:
      - headers:
          - name: X-Canary
            value: "true"
      backendRefs:
        - name: canary-service
          port: 80
          weight: 100
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: stable-service
          port: 80

Use Case 2: Mobile vs Web Routing

rules:
  - matches:
      - headers:
          - name: User-Agent
            type: RegularExpression
            value: ".*Mobile.*"
      backendRefs:
        - name: mobile-service
          port: 80
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: web-service
          port: 80

Troubleshooting

Header Not Matching?

  1. Check header name (case-sensitive in some implementations)
  2. Verify header value exactly matches
  3. Ensure client is sending the header
  4. Check rule order

Query Parameter Not Working?

  1. Verify query parameter name and value
  2. Check URL encoding
  3. Ensure parameter is in the query string
  4. Test with curl: curl "http://example.com?param=value"

Next Steps

Now that you understand advanced routing, let's learn about traffic splitting:

👉 Next: Traffic Splitting →

Sources & References

Version Compatibility: This content is based on Gateway API v1 and NGINX Gateway Fabric 2.2.1. Please verify compatibility with your cluster's Gateway API implementation and version.