Routes

The routes block defines how incoming requests are matched and forwarded to upstreams or handlers. Routes are evaluated by priority, with higher priority routes checked first.

Basic Configuration

routes {
    route "api" {
        priority 100
        matches {
            path-prefix "/api/"
        }
        upstream "backend"
    }

    route "static" {
        priority 50
        matches {
            path-prefix "/static/"
        }
        service-type "static"
        static-files {
            root "/var/www/static"
        }
    }
}

Route Options

Priority

route "api" {
    priority 100
}

Higher priority routes are evaluated first. When multiple routes could match, the highest priority wins.

PriorityTypical Use
1000+Health checks, admin endpoints
100-999API routes
50-99Static files
1-49Catch-all routes

Match Conditions

Routes support multiple match conditions. All conditions within a route must match (AND logic).

Path Matching

matches {
    // Exact path match
    path "/api/v1/users"

    // Prefix match
    path-prefix "/api/"

    // Regex match
    path-regex "^/api/v[0-9]+/.*$"
}
Match TypeExampleMatches
path/users/users only
path-prefix/api//api/, /api/users, /api/v1/data
path-regex^/user/[0-9]+$/user/123, /user/456

Host Matching

matches {
    host "api.example.com"
}

Match by the Host header. Useful for virtual hosting.

Method Matching

matches {
    method "GET" "POST" "PUT" "DELETE"
}

Match specific HTTP methods. Multiple methods are OR’d together.

Header Matching

matches {
    // Match if header exists
    header name="X-Api-Key"

    // Match header with specific value
    header name="X-Api-Version" value="2"
}

Query Parameter Matching

matches {
    // Match if parameter exists
    query-param name="debug"

    // Match parameter with value
    query-param name="format" value="json"
}

Service Types

route "api" {
    service-type "web"  // Default
}
TypeDescription
webStandard HTTP proxy (default)
apiAPI service with JSON error responses
staticStatic file serving
builtinBuilt-in handlers

Static File Serving

route "assets" {
    matches {
        path-prefix "/static/"
    }
    service-type "static"
    static-files {
        root "/var/www/static"
        index "index.html"
        directory-listing false
        cache-control "public, max-age=86400"
        compress true
        fallback "index.html"  // For SPAs
    }
}
OptionDefaultDescription
rootRequiredRoot directory for files
indexindex.htmlDefault index file
directory-listingfalseEnable directory browsing
cache-controlpublic, max-age=3600Cache-Control header
compresstrueEnable gzip/brotli compression
fallbackNoneFallback file for 404s (SPA routing)

Built-in Handlers

route "health" {
    priority 1000
    matches {
        path "/health"
    }
    service-type "builtin"
    builtin-handler "health"
}
HandlerPathDescription
health/healthHealth check (200 OK)
status/statusJSON status with version/uptime
metrics/metricsPrometheus metrics
not-foundAny404 handler
config/admin/configConfiguration dump (admin)
upstreams/admin/upstreamsUpstream health status (admin)

Upstream Reference

route "api" {
    upstream "backend"
}

Reference an upstream defined in the upstreams block. Required for web and api service types.

Filters and Agents

route "api" {
    matches {
        path-prefix "/api/"
    }
    upstream "backend"
    filters "auth" "rate-limit" "cors"
}

Apply filters in order. Filters are defined in the top-level filters block.

Enable WAF shorthand:

route "api" {
    waf-enabled true
}

Route Policies

Header Modifications

route "api" {
    upstream "backend"
    policies {
        request-headers {
            // Set or replace header
            set {
                "X-Forwarded-Proto" "https"
                "X-Request-Start" "${request_time}"
            }
            // Add header (preserves existing)
            add {
                "X-Custom-Header" "value"
            }
            // Remove headers
            remove "X-Internal-Header" "X-Debug"
        }
        response-headers {
            set {
                "X-Content-Type-Options" "nosniff"
                "X-Frame-Options" "DENY"
            }
            remove "Server" "X-Powered-By"
        }
    }
}

Timeout Override

route "upload" {
    matches {
        path-prefix "/upload/"
    }
    upstream "backend"
    policies {
        timeout-secs 300  // 5 minutes for uploads
    }
}

Body Size Limit

route "upload" {
    policies {
        max-body-size "100MB"
    }
}

Supports units: B, KB, MB, GB

Failure Mode

route "api" {
    policies {
        failure-mode "closed"  // Block on failure (default)
    }
}

route "metrics" {
    policies {
        failure-mode "open"    // Allow through on failure
    }
}
ModeBehaviorUse Case
closedBlock traffic on agent/upstream failureSecurity-sensitive routes
openAllow traffic through on failureNon-critical observability

Request/Response Buffering

route "api" {
    policies {
        buffer-requests true   // Buffer full request before forwarding
        buffer-responses true  // Buffer full response before sending
    }
}

Buffering is required for body inspection by agents. Be mindful of memory usage with large bodies.

Retry Policy

route "api" {
    upstream "backend"
    retry-policy {
        max-attempts 3
        timeout-ms 30000
        backoff-base-ms 100
        backoff-max-ms 10000
        retryable-status-codes 502 503 504
    }
}
OptionDefaultDescription
max-attempts3Maximum retry attempts
timeout-ms30000Total timeout for all attempts
backoff-base-ms100Initial backoff delay
backoff-max-ms10000Maximum backoff delay
retryable-status-codes502, 503, 504Status codes to retry

Backoff uses exponential delay: min(base * 2^attempt, max)

Circuit Breaker

route "api" {
    upstream "backend"
    circuit-breaker {
        failure-threshold 5
        success-threshold 2
        timeout-seconds 30
        half-open-max-requests 1
    }
}
OptionDefaultDescription
failure-threshold5Failures before opening circuit
success-threshold2Successes to close circuit
timeout-seconds30Time before trying half-open
half-open-max-requests1Requests allowed in half-open

Circuit breaker states:

  • Closed: Normal operation, requests flow through
  • Open: Requests fail immediately (circuit tripped)
  • Half-Open: Limited requests to test recovery

Error Pages

route "api" {
    error-pages {
        default-format "json"
        pages {
            "404" {
                format "json"
                message "Resource not found"
            }
            "500" {
                format "json"
                message "Internal server error"
            }
            "503" {
                format "html"
                template "/etc/sentinel/errors/503.html"
            }
        }
    }
}
FormatContent-Type
jsonapplication/json
htmltext/html
texttext/plain
xmlapplication/xml

Complete Examples

API Gateway

routes {
    // Health check (highest priority)
    route "health" {
        priority 1000
        matches {
            path "/health"
        }
        service-type "builtin"
        builtin-handler "health"
    }

    // Metrics endpoint (admin only)
    route "metrics" {
        priority 999
        matches {
            path "/metrics"
            header name="X-Admin-Token"
        }
        service-type "builtin"
        builtin-handler "metrics"
    }

    // API v2 (current)
    route "api-v2" {
        priority 200
        matches {
            path-prefix "/api/v2/"
            method "GET" "POST" "PUT" "DELETE" "PATCH"
        }
        upstream "api-v2"
        filters "auth" "rate-limit"
        retry-policy {
            max-attempts 3
            retryable-status-codes 502 503 504
        }
        policies {
            timeout-secs 30
            failure-mode "closed"
            request-headers {
                set {
                    "X-Api-Version" "2"
                }
            }
        }
    }

    // API v1 (legacy)
    route "api-v1" {
        priority 100
        matches {
            path-prefix "/api/v1/"
        }
        upstream "api-v1"
        filters "auth"
        policies {
            timeout-secs 60
            response-headers {
                set {
                    "X-Deprecation-Notice" "API v1 is deprecated. Please migrate to v2."
                }
            }
        }
    }

    // Static assets
    route "static" {
        priority 50
        matches {
            path-prefix "/static/"
        }
        service-type "static"
        static-files {
            root "/var/www/static"
            cache-control "public, max-age=31536000, immutable"
            compress true
        }
    }

    // SPA fallback
    route "spa" {
        priority 1
        matches {
            path-prefix "/"
            method "GET"
        }
        service-type "static"
        static-files {
            root "/var/www/app"
            fallback "index.html"
        }
    }
}

Multi-tenant Routing

routes {
    route "tenant-a" {
        priority 100
        matches {
            host "tenant-a.example.com"
            path-prefix "/api/"
        }
        upstream "tenant-a-backend"
        policies {
            request-headers {
                set {
                    "X-Tenant-Id" "tenant-a"
                }
            }
        }
    }

    route "tenant-b" {
        priority 100
        matches {
            host "tenant-b.example.com"
            path-prefix "/api/"
        }
        upstream "tenant-b-backend"
        policies {
            request-headers {
                set {
                    "X-Tenant-Id" "tenant-b"
                }
            }
        }
    }
}

Default Values

SettingDefault
priority0
service-typeweb
policies.failure-modeclosed
policies.buffer-requestsfalse
policies.buffer-responsesfalse
static-files.indexindex.html
static-files.directory-listingfalse
static-files.compresstrue
retry-policy.max-attempts3
circuit-breaker.failure-threshold5

Route Evaluation Order

  1. Routes sorted by priority (descending)
  2. First matching route wins
  3. If no route matches and listener has default-route, use that
  4. Otherwise, return 404

Next Steps

  • Upstreams - Backend server configuration
  • Limits - Request limits and performance