Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

  • Option represents 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;
  • PhantomData records 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.