The Standard Library as Architecture
Axum’s advanced types are built from ordinary Rust ideas.
Arc makes configured routers cheap to clone
Router<S> contains Arc<RouterInner<S>>. Cloning a router increments shared
ownership instead of copying its route tree. Builder methods use copy-on-write
style internals while the configured application can be cloned per connection.
Source: routing/mod.rs:86
Infallible proves an error cannot escape
The top-level router’s Service::Error is std::convert::Infallible. Matching
on an Infallible value has no branches. This is stronger than “we probably
won’t return errors”: the type system proves that all application failures have
already become HTTP responses.
Result separates extraction from rejection policy
Extractor traits return Result<Self, Self::Rejection>. Their associated
rejection type must implement IntoResponse. The handler adapter uses ordinary
matching and early return to short-circuit the remaining pipeline.
Interestingly, extracting Result<T, T::Rejection> itself is infallible. That
lets a handler inspect a failed extraction and choose its own policy.
Familiar types compose protocols
Optionrepresents optional route methods and response metadata;- tuples represent handler argument lists and layered response parts;
- associated types connect an extractor to its rejection and a service to its response, error, and future;
- marker types distinguish otherwise overlapping generic implementations;
PhantomDatarecords type relationships without runtime storage.
Pinning protects async state
Connection and route futures are pinned before polling. Once an async state
machine may contain references into itself, moving it could invalidate those
references. Pin expresses that its memory location is now stable.
Most application authors never manually pin a handler future. Framework code must, because it builds and delegates custom future state machines.
Ownership communicates lifecycle
The request is moved through the service chain. Parts is mutably borrowed by
metadata extractors; the body remains separately owned until exactly one final
extractor receives it. The response is then moved outward. The signatures are a
lifecycle diagram even before any implementation is read.