|
183 | 183 | //! # let _: Router = app; |
184 | 184 | //! ``` |
185 | 185 | //! |
| 186 | +//! State is cloned for every request. Wrapping your state in `Arc` makes those |
| 187 | +//! clones cheap. If all fields are already cheap to clone (for example, each field |
| 188 | +//! is itself an `Arc` or a copy type), you can `#[derive(Clone)]` directly on the |
| 189 | +//! struct instead. |
| 190 | +//! |
| 191 | +//! ### Substates with `FromRef` |
| 192 | +//! |
| 193 | +//! When a handler only needs part of the application state, use [`FromRef`] to extract |
| 194 | +//! a substate. Implement the trait manually, or derive it with `#[derive(FromRef)]` |
| 195 | +//! (requires the `macros` feature): |
| 196 | +//! |
| 197 | +//! ```rust |
| 198 | +//! use axum::{Router, routing::get, extract::{State, FromRef}}; |
| 199 | +//! |
| 200 | +//! #[derive(Clone)] |
| 201 | +//! struct AppState { |
| 202 | +//! api_state: ApiState, |
| 203 | +//! } |
| 204 | +//! |
| 205 | +//! #[derive(Clone)] |
| 206 | +//! struct ApiState {} |
| 207 | +//! |
| 208 | +//! // Teach axum how to produce an `ApiState` from a reference to `AppState`. |
| 209 | +//! impl FromRef<AppState> for ApiState { |
| 210 | +//! fn from_ref(app_state: &AppState) -> ApiState { |
| 211 | +//! app_state.api_state.clone() |
| 212 | +//! } |
| 213 | +//! } |
| 214 | +//! |
| 215 | +//! let app = Router::new() |
| 216 | +//! .route("/", get(handler)) |
| 217 | +//! .with_state(AppState { api_state: ApiState {} }); |
| 218 | +//! |
| 219 | +//! // This handler receives only the `ApiState` slice; it never sees `AppState`. |
| 220 | +//! async fn handler(State(api_state): State<ApiState>) {} |
| 221 | +//! # let _: Router = app; |
| 222 | +//! ``` |
| 223 | +//! |
| 224 | +//! ### The `Router<S>` type parameter |
| 225 | +//! |
| 226 | +//! `Router<S>` when `S` is not `()` means a router that is _missing_ a state of type `S`. Calling |
| 227 | +//! [`.with_state(s)`][Router::with_state] provides that state and typically produces a |
| 228 | +//! `Router<()>`, which is the only form that can be passed to [`serve()`]. See |
| 229 | +//! [`Router::with_state`] for a full explanation. |
| 230 | +//! |
186 | 231 | //! You should prefer using [`State`] if possible since it's more type safe. The downside is that |
187 | 232 | //! it's less dynamic than task-local variables and request extensions. |
188 | 233 | //! |
|
426 | 471 | //! [load shed]: tower::load_shed |
427 | 472 | //! [`axum-core`]: http://crates.io/crates/axum-core |
428 | 473 | //! [`State`]: crate::extract::State |
| 474 | +//! [`FromRef`]: crate::extract::FromRef |
| 475 | +//! [`Router::with_state`]: crate::routing::Router::with_state |
429 | 476 |
|
430 | 477 | #![cfg_attr(docsrs, feature(doc_cfg))] |
431 | 478 | #![cfg_attr(test, allow(clippy::float_cmp))] |
|
0 commit comments