All Features
This page is a single-page reference for everything the crate ships. Items that require an opt-in feature flag are annotated with the flag name in backticks.
Server / Protocol
- HTTP/1.1 — keep-alive, chunked transfer encoding, gzip compression, ETags, range requests, 30-second per-connection read timeout
- HTTP/2 — ALPN negotiation, full multiplexing, forbidden-header stripping,
Alt-Svcadvertisement —http2 - HTTP/3 / QUIC — UDP listener via
quinn,h3+h3-quinn, QUIC connection-level SNI —http3(default) - TLS —
rustlswithaws-lc-rscrypto backend; no system OpenSSL dependency; FIPS-compatible —http2 - mTLS — client certificate verification via
WebPkiClientVerifier; setRWS_CONFIG_TLS_CLIENT_CA_FILE—http2 - Virtual-host routing — per-domain TLS certificates via
SniCertResolver;.with_host("example.com")on anyRouter—http2 - HTTP → HTTPS redirect —
Server::run_redirect()listens on a second port and issues301responses —http2 - ACME / automatic TLS — automatic certificate provisioning compatible with Let’s Encrypt —
acme - Hot reload —
SIGHUP(orPOST /admin/config/reload) reloads CORS rules, rate limits, log format, and TLS certs without restarting —http2 - Graceful shutdown —
SIGINT/SIGTERMdrain in-flight requests before exit;SERVER_READYflag cleared on shutdown - Gzip compression — applied automatically based on
Accept-Encoding; configurable minimum size - Static file serving — directory listing disabled by default; chunked file streaming for large files; ETag +
Last-Modifiedcaching headers - Thread pool (http1 only) — hand-rolled
ThreadPool; connection-per-thread; no tokio —http1 - Tokio async runtime — used for
http2andhttp3builds;http1is fully synchronous
Routing & App Building
App— zero-config entry point; wraps all built-in controllers (static files, CORS, health, metrics, MCP, …)App::with_state(S)— state-aware dynamic router;Arc<S>shared across all handlers; builder methods.get(),.post(),.put(),.patch(),.delete()App::with_async_state(S)— same API withasync fnhandlers —http2routes!macro — ergonomic route registration:GET "/path" => handler—macrosRouter— standalone path-based router with named parameters (:name) and trailing wildcards (*name);PathParams::get(name)Controllertrait — low-levelis_matching/processinterface; register inApp::executefor maximum control- Typed extractors —
Body(raw bytes),BodyText(UTF-8),Query(parsed query string),RequestHeaders(case-insensitive header map) - Typed errors —
AppErrorenum (BadRequest,Unauthorized,Forbidden,NotFound,Conflict,UnprocessableEntity,TooManyRequests,Internal) withIntoResponsetrait Middlewaretrait —handle(request, connection, next) -> Result<Response, String>; compose via.wrap(layer)WithMiddleware<A>— wraps anyApplication; layers applied in push order (first-pushed is outermost)- Tera templates — render
.htmltemplates with aserde_json::Valuecontext viatera::render—tera - In-process test client —
TestClient::new(app)dispatches requests without opening a TCP socket; use in unit and integration tests - WebSocket — RFC 6455 handshake and frame codec built in; no third-party WebSocket library
- SSE (Server-Sent Events) —
Ssebuilder for streaming events; ideal for streaming AI model output - Background scheduler —
Scheduler::new().every(duration, fn).cron("…", fn).start()
Proxy & Gateway
ReverseProxy— HTTP/1.1 reverse proxy middleware; round-robin backend selectionH2ReverseProxy— HTTP/2 upstream proxy usingtokio::task::block_in_placeto bridge sync middleware —http2GrpcProxy— wrapsH2ReverseProxy; filters onContent-Type: application/grpc*—http2TcpProxy— standalone L4 TCP proxy; bidirectionalstd::io::copyrelay; round-robin backendsUdpProxy— standalone UDP datagram proxy; per-datagram ephemeral socket; round-robin backendsWsProxy— standalone WebSocket proxy; relays raw bytes after upgrade handshake- Config-driven proxy mode —
rws.config.tomlwith[[upstream]]+[[route]]sections; no code required - Health checking — per-upstream background health checker; dead backends removed automatically; configurable thresholds and intervals
- Load balancing — atomic round-robin across live backends
RewriteLayer— rewrite request headers, URI, and response headers / body / status code per route- Per-route rate limiting —
PerRouteRateLimitin config-driven mode;RateLimitLayerin code - Per-route Bearer auth —
BearerAuthMiddlewarein config-driven mode;JwtLayerin code - Route matching — host, path prefix, exact path, HTTP method,
Content-Typeprefix; first-match wins
Security
RateLimitLayer— sliding-window rate limiter keyed by client IP; global singleton viarate_limit::global(); returns429when budget exceededBasicAuthLayer— HTTP Basic authentication middlewareJwtLayer— JWT Bearer token validation middleware —authIpFilter— allowlist / denylist middleware keyed by client IPcrypto— Argon2id password hashing and verification —crypto- CSRF tokens — secure random token generation and validation —
csrf - SSO / OAuth 2.0 / OIDC — RSA and ECDSA signing, outbound HTTPS token exchange —
sso - CORS — built-in CORS controller; configurable origins, methods, and headers; hot-reloadable
- mTLS — mutual TLS client certificate verification —
http2 - No OpenSSL — TLS via
rustls+aws-lc-rs; fully static binaries
Observability & Ops
/healthz— liveness probe; always200 OKwhile the server is up/readyz— readiness probe; returns503after graceful shutdown begins (SERVER_READYflag)/metrics— Prometheus text-format scrape endpointMetricsLayer— per-routerws_route_requests_total{method,path,status}counters andrws_route_duration_seconds{method,path}histograms- Global metrics —
record_request(),record_error(),connection_open()/connection_close()counters OtelLayer— OpenTelemetry trace propagation middlewareCacheLayer— response caching middleware- Structured logging —
RWS_CONFIG_LOG_FORMAT=combined(default) orjson; hot-reloadable - Config hot reload —
SIGHUPorPOST /admin/config/reloadreloads CORS, rate limits, log format, TLS certs; no restart required - Kubernetes-ready —
/healthz,/readyz,/metricsall built in; gracefulSIGTERMdrain; static binary with no system dependencies
AI & MCP
McpServer— implementsApplication; serves the MCP Streamable HTTP protocol (POST /mcp, JSON-RPC 2.0)- Tool registration —
.tool(name, description, schema, handler)— any function returning a string - Resource registration —
.resource(uri_template, name, description, handler) - Prompt registration —
.prompt(name, description, handler) - Bearer auth gate —
.require_bearer(token)gates all MCP requests behind a static token - Fallthrough —
.wrap(app)passes non-MCP requests to anotherApplication - Built-in rws tools —
server_config,feature_flags,server_metrics,rate_limit_config,check_rate_limit,cors_config,list_static_files,reload_config - SSE streaming —
Ssebuilder for streaming AI tokens to browser clients
Database / ORM
All ORM features require exactly one of model-sqlite, model-postgres, or model-mysql.
#[derive(Model)]— generatesimpl Model,Struct::repository(),Struct::query()—macros- Table and column mapping —
#[table(name = "…")],#[column(name = "…")],#[primary_key],#[primary_key(auto_increment)],#[ignore] DbConnection—execute,query_rows,begin,commit,rollback,transaction(closure),query::<T>,migrateDbPool— pre-created connection pool;Mutex<Vec<DbConnection>>;PooledConnectionreturned to pool onDropRepository<T, ID>—save(INSERT or UPDATE by primary key),find_by_id,find_all,deleteQueryBuilder— fluentwhere_eq,fetch_all,fetch_one,count,delete,update; placeholder tokens auto-converted to?(SQLite/MySQL) or$N(PostgreSQL)- Migrations — reads
*.sqlfiles in lexicographic order;_schema_migrationstable tracks applied versions; each migration wrapped in a transaction - Relations —
HasMany<T>,HasOne<O>,BelongsTo<O>with explicit.load(&mut conn); no lazy loading, no hidden N+1 queries - SQLite — bundled
libsqlite3; no system dependency —model-sqlite - PostgreSQL —
postgresclient —model-postgres - MySQL / MariaDB —
mysqlclient —model-mysql
Dependency Injection
Container—TypeId-keyed service store for concrete types anddyn Traitobjectsregister::<T>(value)— wraps inArc<T>, keyed byTypeId::of::<T>()provide::<T: ?Sized>(Arc<T>)— stores trait objects directly- Named services —
get_named::<T>(name)/register_named::<T>(name, value)for multiple instances of the same type into_arc()— seals the container asArc<Container>for sharing across handlers- No external dependencies