Skip to content

Proxy Overview

rust-web-server ships a full-featured proxy stack. You can use it in two distinct ways depending on how much control you need.

Mode 1 — Config-driven proxy (no code)

Drop a rws.config.toml file next to the binary and run rws. As soon as the file contains at least one [[route]] or [[upstream]] section, the server automatically switches into proxy mode. No Rust code is required.

rws.config.toml
[[upstream]]
name = "api"
backends = ["localhost:3000", "localhost:3001"]
[[route]]
name = "api-proxy"
[route.match]
path = "/api/*"
[route.action]
type = "proxy"
[route.action.proxy]
upstream = "api"
Terminal window
rws # proxy mode activated automatically

Best for: ops teams, sidecar containers, API gateways, and situations where you just need to route traffic without touching Rust.

Mode 2 — Library / programmatic

Add rust-web-server as a dependency and compose the proxy middleware stack in code.

use rust_web_server::app::App;
use rust_web_server::core::New;
use rust_web_server::proxy::ReverseProxy;
let app = App::new()
.wrap(ReverseProxy::new(["http://backend:3000"])
.path_prefix("/api"));
Server::new().run(app);

Best for: services that need custom routing logic, per-request auth, conditional proxying, or tight integration with application code.

Side-by-side comparison

Config-drivenLibrary
Requires Rust codeNoYes
Hot-reload via SIGHUPYes (routes + upstreams)No
Health checksYes (built-in)Manual (BackendPool + CircuitBreaker)
L4 TCP / UDP / WS proxiesYes (config sections)Yes (standalone structs)
Path rewritingYes (strip_path_prefix, add_path_prefix)Yes (RewriteLayer)
Per-route rate limitingYesYes (RateLimitLayer)
Bearer authYes (token from env var)Yes (JwtLayer, BasicAuthLayer)
gRPCYes (type = "grpc")Yes (GrpcProxy, requires http2 feature)
Canary / traffic splittingNo (planned)Yes (CanaryLayer)
Service discoveryNo (planned)Yes (BackendPool)
Circuit breaker / retryNo (planned)Yes (CircuitBreaker, RetryLayer)

Detection logic

At startup main() calls ProxyConfig::is_proxy_mode(), which reads rws.config.toml (or the path in RWS_CONFIG_FILE) and returns true if the text contains [[route]] or [[upstream]]. When true, build_from_file() compiles the config into a ConfigDrivenApp that replaces the default App.