Axum: Orientation
Axum is a useful study because its pleasant public API hides a rigorous set of
adapters. An async function is not inherently an HTTP service. Axum connects
that function to the network by converting every stage to a small set of shared
protocols: HTTP request and response types, futures, and Tower’s Service.
The architectural center
TCP listener → Hyper connection → Tower Service → Router → Handler
↓
extract → await → respond
Axum does not implement an async runtime or HTTP parser. Tokio supplies the runtime and sockets. Hyper drives HTTP connections and request bodies. Tower supplies the composable service and middleware vocabulary. Axum’s center is the type-safe adaptation between an ergonomic handler and those lower-level parts.
Design thesis
Axum keeps handlers ordinary by adapting their typed arguments and futures into Tower services, making HTTP composition reuse one readiness-and-call vocabulary from routing down to middleware.
- Extractors turn request ownership into typed handler inputs.
- Response conversion lets domain-shaped returns satisfy HTTP uniformly.
- Tower layers add policy without changing handler signatures.
- Tokio and Hyper own scheduling and transport; Axum owns adaptation.
Crate boundaries
axum-coredefines foundational extraction, body, and response traits;axumprovides routing, handlers, middleware, serving, and built-in extractors;axum-macrosimproves ergonomics and compiler diagnostics;axum-extracontains useful features that need not enlarge the core API;examplesdemonstrates production-shaped composition.
The most important question
Do not begin with Router::route. Begin with this:
How does
async fn create_user(State(db), Json(input)) -> Result<...>become a cloneable service that Hyper can call concurrently?
Answering that question exposes the repository’s generics, macro-generated trait implementations, ownership rules, error model, and async boundaries.
What we will preserve
The reconstruction at the end will preserve route and method dispatch, sequential extraction with a single body consumer, handler futures, response conversion, middleware, explicit capacity limits, cancellation by dropping an in-flight request future, and graceful connection draining.
It will not reproduce HTTP parsing, every extractor, tuple arities, WebSockets, macros, or Tower’s entire type ecosystem.