A3S Gateway
Routing
Rule-based request matching with Host, Path, Headers, Method, and SNI matchers
Routing
A3S Gateway uses a Traefik-compatible rule syntax for matching incoming requests to services.
Rule Syntax
rule = "Matcher(`value`) && Matcher(`value`)"Supported Matchers
Prop
Type
Combining Matchers
Use && to combine multiple matchers (AND logic):
routers "api-v1" {
rule = "Host(`api.example.com`) && PathPrefix(`/v1`)"
service = "api-v1"
}
routers "webhooks" {
rule = "Method(`POST`) && PathPrefix(`/webhooks`)"
service = "webhook-handler"
}
routers "internal" {
rule = "Headers(`X-Internal`, `true`) && PathPrefix(`/admin`)"
service = "admin-service"
}Priority
When multiple routers match, the lowest priority value wins (default: 0):
routers "specific" {
rule = "Host(`api.example.com`) && Path(`/health`)"
service = "health-service"
priority = 0
}
routers "general" {
rule = "Host(`api.example.com`)"
service = "api-service"
priority = 10
}Entrypoint Binding
Routers only receive traffic from their bound entrypoints:
entrypoints "web" {
address = "0.0.0.0:80"
}
entrypoints "websecure" {
address = "0.0.0.0:443"
tls {
cert_file = "cert.pem"
key_file = "key.pem"
}
}
# HTTPS only
routers "api" {
rule = "Host(`api.example.com`)"
service = "api-service"
entrypoints = ["websecure"]
}
# Both HTTP and HTTPS
routers "web" {
rule = "Host(`www.example.com`)"
service = "web-service"
entrypoints = ["web", "websecure"]
}Middleware Chain
Middlewares are applied in the order listed. If any middleware rejects the request, the pipeline short-circuits immediately.
routers "api" {
rule = "Host(`api.example.com`)"
service = "api-service"
middlewares = ["ip-allow", "auth-jwt", "rate-limit", "cors"]
# Order: IP check → JWT auth → rate limit → CORS headers
}TCP/UDP Routing
TCP entrypoints use SNI from the TLS ClientHello:
entrypoints "tcp-secure" {
address = "0.0.0.0:5432"
protocol = "tcp"
}
routers "postgres" {
rule = "HostSNI(`db.example.com`)"
service = "postgres-service"
entrypoints = ["tcp-secure"]
}UDP routing is port-based — each UDP entrypoint maps to a single service.
Examples
API Versioning
routers "api-v2" {
rule = "Host(`api.example.com`) && PathPrefix(`/v2`)"
service = "api-v2"
priority = 0
}
routers "api-v1" {
rule = "Host(`api.example.com`) && PathPrefix(`/v1`)"
service = "api-v1"
priority = 1
}
routers "api-fallback" {
rule = "Host(`api.example.com`)"
service = "api-v2"
priority = 100
}Multi-Tenant
routers "tenant-a" {
rule = "Host(`a.example.com`)"
service = "tenant-a-backend"
}
routers "tenant-b" {
rule = "Host(`b.example.com`)"
service = "tenant-b-backend"
}Header-Based Canary
routers "canary" {
rule = "Headers(`X-Canary`, `true`) && PathPrefix(`/api`)"
service = "canary-backend"
priority = 0
}
routers "stable" {
rule = "PathPrefix(`/api`)"
service = "stable-backend"
priority = 10
}