mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-07 00:00:15 +02:00
docs: consolidate state management docs in crate root (#3683)
Co-authored-by: Yann Simon <[email protected]>
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
/// Used to do reference-to-value conversions thus not consuming the input value.
|
||||
///
|
||||
/// This is mainly used with [`State`] to extract "substates" from a reference to main application
|
||||
/// state.
|
||||
/// state. See ["Sharing state with handlers"][sharing-state] for a worked example.
|
||||
///
|
||||
/// See [`State`] for more details on how library authors should use this trait.
|
||||
///
|
||||
/// This trait can be derived using `#[derive(FromRef)]`.
|
||||
///
|
||||
/// [`State`]: https://docs.rs/axum/0.8/axum/extract/struct.State.html
|
||||
/// [sharing-state]: https://docs.rs/axum/0.8/axum/index.html#sharing-state-with-handlers
|
||||
// NOTE: This trait is defined in axum-core, even though it is mainly used with `State` which is
|
||||
// defined in axum. That allows crate authors to use it when implementing extractors.
|
||||
pub trait FromRef<T> {
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
Provide the state for the router. State passed to this method is global and will be used
|
||||
for all requests this router receives. That means it is not suitable for holding state derived from a request, such as authorization data extracted in a middleware. Use [`Extension`] instead for such data.
|
||||
|
||||
See ["Sharing state with handlers"][sharing-state] for an overview of state patterns,
|
||||
including when to use `Arc`, how to extract substates with [`FromRef`], and what the
|
||||
`Router<S>` type parameter means.
|
||||
|
||||
[sharing-state]: crate#sharing-state-with-handlers
|
||||
[`FromRef`]: crate::extract::FromRef
|
||||
|
||||
```rust
|
||||
use axum::{Router, routing::get, extract::State};
|
||||
|
||||
|
||||
@@ -7,12 +7,17 @@ use std::{
|
||||
|
||||
/// Extractor for state.
|
||||
///
|
||||
/// See ["Sharing state with handlers"][sharing-state] for an overview of all approaches to
|
||||
/// sharing state, including when to use `Arc`, how `FromRef` substates work, and what the
|
||||
/// `Router<S>` type parameter means.
|
||||
///
|
||||
/// See ["Accessing state in middleware"][state-from-middleware] for how to
|
||||
/// access state in middleware.
|
||||
///
|
||||
/// State is global and used in every request a router with state receives.
|
||||
/// For accessing data derived from requests, such as authorization data, see [`Extension`].
|
||||
///
|
||||
/// [sharing-state]: crate#sharing-state-with-handlers
|
||||
/// [state-from-middleware]: crate::middleware#accessing-state-in-middleware
|
||||
/// [`Extension`]: crate::Extension
|
||||
///
|
||||
|
||||
@@ -183,6 +183,51 @@
|
||||
//! # let _: Router = app;
|
||||
//! ```
|
||||
//!
|
||||
//! State is cloned for every request. Wrapping your state in `Arc` makes those
|
||||
//! clones cheap. If all fields are already cheap to clone (for example, each field
|
||||
//! is itself an `Arc` or a copy type), you can `#[derive(Clone)]` directly on the
|
||||
//! struct instead.
|
||||
//!
|
||||
//! ### Substates with `FromRef`
|
||||
//!
|
||||
//! When a handler only needs part of the application state, use [`FromRef`] to extract
|
||||
//! a substate. Implement the trait manually, or derive it with `#[derive(FromRef)]`
|
||||
//! (requires the `macros` feature):
|
||||
//!
|
||||
//! ```rust
|
||||
//! use axum::{Router, routing::get, extract::{State, FromRef}};
|
||||
//!
|
||||
//! #[derive(Clone)]
|
||||
//! struct AppState {
|
||||
//! api_state: ApiState,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Clone)]
|
||||
//! struct ApiState {}
|
||||
//!
|
||||
//! // Teach axum how to produce an `ApiState` from a reference to `AppState`.
|
||||
//! impl FromRef<AppState> for ApiState {
|
||||
//! fn from_ref(app_state: &AppState) -> ApiState {
|
||||
//! app_state.api_state.clone()
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! let app = Router::new()
|
||||
//! .route("/", get(handler))
|
||||
//! .with_state(AppState { api_state: ApiState {} });
|
||||
//!
|
||||
//! // This handler receives only the `ApiState` slice; it never sees `AppState`.
|
||||
//! async fn handler(State(api_state): State<ApiState>) {}
|
||||
//! # let _: Router = app;
|
||||
//! ```
|
||||
//!
|
||||
//! ### The `Router<S>` type parameter
|
||||
//!
|
||||
//! `Router<S>` when `S` is not `()` means a router that is _missing_ a state of type `S`. Calling
|
||||
//! [`.with_state(s)`][Router::with_state] provides that state and typically produces a
|
||||
//! `Router<()>`, which is the only form that can be passed to [`serve()`]. See
|
||||
//! [`Router::with_state`] for a full explanation.
|
||||
//!
|
||||
//! You should prefer using [`State`] if possible since it's more type safe. The downside is that
|
||||
//! it's less dynamic than task-local variables and request extensions.
|
||||
//!
|
||||
@@ -426,6 +471,8 @@
|
||||
//! [load shed]: tower::load_shed
|
||||
//! [`axum-core`]: http://crates.io/crates/axum-core
|
||||
//! [`State`]: crate::extract::State
|
||||
//! [`FromRef`]: crate::extract::FromRef
|
||||
//! [`Router::with_state`]: crate::routing::Router::with_state
|
||||
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![cfg_attr(test, allow(clippy::float_cmp))]
|
||||
|
||||
Reference in New Issue
Block a user