You are reading the docs for rws 18.21 The latest release is 18.24. Read this page for the latest release.

Cookbook: API gateway

Several services behind one API host — path routing, JWT auth, per-route rate limits, response caching, CORS, retries and circuit breaking.

One public host, a service per path prefix, JWT on everything but the public catalogue, stricter limits on writes, and the catalogue cached:

port = 443
http_redirect_port = 80

[acme]
domains = ["api.example.com"]
email   = "ops@example.com"

[cors]
allow_origins = "https://app.example.com"
allow_methods = "GET,POST,PUT,PATCH,DELETE,OPTIONS"
allow_headers = "content-type,authorization"

[rate_limit]                        # every client, every route
max_requests = 600
window_secs  = 60

[[upstream]]
name = "catalog"
backends = ["10.0.1.10:8080", "10.0.1.11:8080"]
[upstream.health_check]
path = "/healthz"
[upstream.circuit_breaker]
failure_threshold = 5
recovery_secs     = 30

[[upstream]]
name = "orders"
backends = ["10.0.2.10:8080", "10.0.2.11:8080"]
[upstream.retry]
attempts = 2

[[route]]
name = "catalog"
[route.match]
path   = "/v1/products/*"
method = "GET"
[route.action]
type = "proxy"
upstream = "catalog"
strip_path_prefix = "/v1"
[route.middleware.cache]
ttl_secs = 30
vary_by  = ["Accept-Language"]

[[route]]
name = "orders"
[route.match]
path = "/v1/orders/*"
[route.action]
type = "proxy"
upstream = "orders"
strip_path_prefix = "/v1"
[route.middleware.auth]
type       = "jwt"
secret_env = "JWT_SECRET"
[route.middleware.rate_limit]
max_requests = 60
window_secs  = 60

[[route]]
name = "health"
[route.match]
path = "/healthz"
[route.action]
type   = "respond"
status = 200
body   = "ok"

Requests get Proxy-Status and errors come back as RFC 9457 application/problem+json; rws_upstream_* metrics on /metrics show each backend's latency, retries and breaker state. Rotate JWT_SECRET without logging anyone out with previous_secret_env (key rotation).

Edit this page on GitHub