astor
HTTP for Rust services behind a reverse proxy. Does its job. Goes home.
Two dependencies — [matchit] for routing, tokio for async I/O. No hyper. No middleware stack you didn't ask for.
The idea
You're running behind nginx. nginx already handles TLS, rate limiting, slow clients, and body-size limits. Every general-purpose Rust HTTP framework re-implements all of that. astor doesn't — that's the whole point.
What changes between services is exactly what astor covers:
- Routing — radix tree, O(path-length),
{name}parameter syntax - Typed responses — named status codes, response shortcuts, typed builder
- Graceful shutdown — SIGTERM / Ctrl-C, drains in-flight requests before exit
Quick start
# Cargo.toml
[]
= "0.3"
= { = "1", = ["rt-multi-thread", "macros"] }
use ;
async
// Path params: {name} syntax — req.param("id") → Option<&str>
async
// Query params pre-parsed — req.query("key") → Option<&str>
// GET /users?page=2&limit=10 still matches the /users route
async
// req.body() → &[u8] — parse with serde_json, simd-json, or anything else
async
// Return Status directly — astor wraps it into a response
async
Middleware
Middleware runs as an ordered chain: global (router-level) first, then per-route extras, then the handler. The chain is baked into each route at startup — no runtime composition.
use ;
async
async
Global middleware applies to every route registered after .middleware():
let users = new
.middleware // applied to all routes below
.on // chain: [require_auth]
.on // chain: [require_auth, ownership_check]
.on;
Sub-router composition via .merge() — each sub-router keeps its own chain:
let public = new.on;
let users = new.middleware.on;
let products = new.middleware.on;
let app = new.merge.merge.merge;
bind.serve.await.unwrap;
Pass () as the fourth argument to .on() when a route needs no extra middleware.
Status codes are a type, not a number
No free-form response constructor. No raw integers. Every status code is a named [Status] variant — tab-completable, greppable, compiler-verified.
status // 204 — not "204", not 204
status // 404
builder
.status
.header
.json
// Return Status directly from a handler
async
Every IANA-registered code from 100 to 511 — full list on docs.rs/astor.
Full API reference, nginx config, and Kubernetes deployment guide: docs.rs/astor
Contributing
Contributions are welcome. Read CONTRIBUTING.md before opening a PR. See CHANGELOG.md for release history.
License
MIT