Struct State
pub struct State<S>(pub S);Expand description
Extractor for state.
See โAccessing state in 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.
ยงWith Router
use axum::{Router, routing::get, extract::State};
// the application state
//
// here you can put configuration, database connection pools, or whatever
// state you need
#[derive(Clone)]
struct AppState {}
let state = AppState {};
// create a `Router` that holds our state
let app = Router::new()
.route("/", get(handler))
// provide the state so the router can access it
.with_state(state);
async fn handler(
// access the state via the `State` extractor
// extracting a state of the wrong type results in a compile error
State(state): State<AppState>,
) {
// use `state`...
}Note that State is an extractor, so be sure to put it before any body
extractors, see โthe order of extractorsโ.
ยงCombining stateful routers
Multiple Routers can be combined with Router::nest or Router::merge
When combining Routers with one of these methods, the Routers must have
the same state type. Generally, this can be inferred automatically:
use axum::{Router, routing::get, extract::State};
#[derive(Clone)]
struct AppState {}
let state = AppState {};
// create a `Router` that will be nested within another
let api = Router::new()
.route("/posts", get(posts_handler));
let app = Router::new()
.nest("/api", api)
.with_state(state);
async fn posts_handler(State(state): State<AppState>) {
// use `state`...
}However, if you are composing Routers that are defined in separate scopes,
you may need to annotate the State type explicitly:
use axum::{Router, routing::get, extract::State};
#[derive(Clone)]
struct AppState {}
fn make_app() -> Router {
let state = AppState {};
Router::new()
.nest("/api", make_api())
.with_state(state) // the outer Router's state is inferred
}
// the inner Router must specify its state type to compose with the
// outer router
fn make_api() -> Router<AppState> {
Router::new()
.route("/posts", get(posts_handler))
}
async fn posts_handler(State(state): State<AppState>) {
// use `state`...
}In short, a Routerโs generic state type defaults to ()
(no state) unless Router::with_state is called or the value
of the generic type is given explicitly.
ยงWith MethodRouter
use axum::{routing::get, extract::State};
#[derive(Clone)]
struct AppState {}
let state = AppState {};
let method_router_with_state = get(handler)
// provide the state so the handler can access it
.with_state(state);
async fn handler(State(state): State<AppState>) {
// use `state`...
}ยงWith Handler
use axum::{routing::get, handler::Handler, extract::State};
#[derive(Clone)]
struct AppState {}
let state = AppState {};
async fn handler(State(state): State<AppState>) {
// use `state`...
}
// provide the state so the handler can access it
let handler_with_state = handler.with_state(state);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, handler_with_state.into_make_service()).await.unwrap();ยงSubstates
State only allows a single state type but you can use FromRef to extract โsubstatesโ:
use axum::{Router, routing::get, extract::{State, FromRef}};
// the application state
#[derive(Clone)]
struct AppState {
// that holds some api specific state
api_state: ApiState,
}
// the api specific state
#[derive(Clone)]
struct ApiState {}
// support converting an `AppState` in an `ApiState`
impl FromRef<AppState> for ApiState {
fn from_ref(app_state: &AppState) -> ApiState {
app_state.api_state.clone()
}
}
let state = AppState {
api_state: ApiState {},
};
let app = Router::new()
.route("/", get(handler))
.route("/api/users", get(api_users))
.with_state(state);
async fn api_users(
// access the api specific state
State(api_state): State<ApiState>,
) {
}
async fn handler(
// we can still access to top level state
State(state): State<AppState>,
) {
}For convenience FromRef can also be derived using #[derive(FromRef)].
ยงFor library authors
If youโre writing a library that has an extractor that needs state, this is the recommended way to do it:
use axum_core::extract::{FromRequestParts, FromRef};
use http::request::Parts;
use std::convert::Infallible;
// the extractor your library provides
struct MyLibraryExtractor;
impl<S> FromRequestParts<S> for MyLibraryExtractor
where
// keep `S` generic but require that it can produce a `MyLibraryState`
// this means users will have to implement `FromRef<UserState> for MyLibraryState`
MyLibraryState: FromRef<S>,
S: Send + Sync,
{
type Rejection = Infallible;
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
// get a `MyLibraryState` from a reference to the state
let state = MyLibraryState::from_ref(state);
// ...
}
}
// the state your library needs
struct MyLibraryState {
// ...
}ยงShared mutable state
As state is global within a Router you canโt directly get a mutable reference to
the state.
The most basic solution is to use an Arc<Mutex<_>>. Which kind of mutex you need depends on
your use case. See the tokio docs for more details.
Note that holding a locked std::sync::Mutex across .await points will result in !Send
futures which are incompatible with axum. If you need to hold a mutex across .await points,
consider using a tokio::sync::Mutex instead.
ยงExample
use axum::{Router, routing::get, extract::State};
use std::sync::{Arc, Mutex};
#[derive(Clone)]
struct AppState {
data: Arc<Mutex<String>>,
}
async fn handler(State(state): State<AppState>) {
{
let mut data = state.data.lock().expect("mutex was poisoned");
*data = "updated foo".to_owned();
}
// ...
}
let state = AppState {
data: Arc::new(Mutex::new("foo".to_owned())),
};
let app = Router::new()
.route("/", get(handler))
.with_state(state);Tuple Fieldsยง
ยง0: STrait Implementationsยง
ยงimpl<OuterState, InnerState> FromRequestParts<OuterState> for State<InnerState>
impl<OuterState, InnerState> FromRequestParts<OuterState> for State<InnerState>
ยงtype Rejection = Infallible
type Rejection = Infallible
ยงasync fn from_request_parts(
_parts: &mut Parts,
state: &OuterState,
) -> Result<State<InnerState>, <State<InnerState> as FromRequestParts<OuterState>>::Rejection>
async fn from_request_parts( _parts: &mut Parts, state: &OuterState, ) -> Result<State<InnerState>, <State<InnerState> as FromRequestParts<OuterState>>::Rejection>
impl<S> Copy for State<S>where
S: Copy,
Auto Trait Implementationsยง
impl<S> Freeze for State<S>where
S: Freeze,
impl<S> RefUnwindSafe for State<S>where
S: RefUnwindSafe,
impl<S> Send for State<S>where
S: Send,
impl<S> Sync for State<S>where
S: Sync,
impl<S> Unpin for State<S>where
S: Unpin,
impl<S> UnwindSafe for State<S>where
S: UnwindSafe,
Blanket Implementationsยง
ยงimpl<T, A, P> Access<T> for P
impl<T, A, P> Access<T> for P
Sourceยงimpl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
Sourceยงfn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
Sourceยงfn adapt_into(self) -> D
fn adapt_into(self) -> D
Sourceยงimpl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
Sourceยงfn arrays_from(colors: C) -> T
fn arrays_from(colors: C) -> T
Sourceยงimpl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
Sourceยงfn arrays_into(self) -> C
fn arrays_into(self) -> C
Sourceยงimpl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Sourceยงfn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Sourceยงimpl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
Sourceยงtype Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
parameters when converting.Sourceยงfn cam16_into_unclamped(
self,
parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>,
) -> T
fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T
self into C, using the provided parameters.Sourceยงimpl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Sourceยงimpl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
Sourceยงfn components_from(colors: C) -> T
fn components_from(colors: C) -> T
ยงimpl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
ยงfn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.ยงfn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.ยงfn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Anyโs vtable from &Traitโs.ยงfn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Anyโs vtable from &mut Traitโs.ยงimpl<T> DowncastSend for T
impl<T> DowncastSend for T
ยงimpl<T> DowncastSync for T
impl<T> DowncastSync for T
ยงimpl<T, A> DynAccess<T> for Awhere
A: Access<T>,
<A as Access<T>>::Guard: 'static,
impl<T, A> DynAccess<T> for Awhere
A: Access<T>,
<A as Access<T>>::Guard: 'static,
Sourceยงimpl<T> FromAngle<T> for T
impl<T> FromAngle<T> for T
Sourceยงfn from_angle(angle: T) -> T
fn from_angle(angle: T) -> T
angle.ยงimpl<S, T> FromRequest<S, ViaParts> for T
impl<S, T> FromRequest<S, ViaParts> for T
ยงtype Rejection = <T as FromRequestParts<S>>::Rejection
type Rejection = <T as FromRequestParts<S>>::Rejection
ยงfn from_request(
req: Request<Body>,
state: &S,
) -> impl Future<Output = Result<T, <T as FromRequest<S, ViaParts>>::Rejection>>
fn from_request( req: Request<Body>, state: &S, ) -> impl Future<Output = Result<T, <T as FromRequest<S, ViaParts>>::Rejection>>
Sourceยงimpl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
Sourceยงfn from_stimulus(other: U) -> T
fn from_stimulus(other: U) -> T
other into Self, while performing the appropriate scaling,
rounding and clamping.ยงimpl<T> Instrument for T
impl<T> Instrument for T
ยงfn instrument(self, span: Span) -> Instrumented<Self> โ
fn instrument(self, span: Span) -> Instrumented<Self> โ
Sourceยงimpl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
Sourceยงfn into_angle(self) -> U
fn into_angle(self) -> U
T.Sourceยงimpl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
Sourceยงtype Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
parameters when converting.Sourceยงfn into_cam16_unclamped(
self,
parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>,
) -> T
fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T
self into C, using the provided parameters.Sourceยงimpl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
Sourceยงfn into_color(self) -> U
fn into_color(self) -> U
Sourceยงimpl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
Sourceยงfn into_color_unclamped(self) -> U
fn into_color_unclamped(self) -> U
Sourceยงimpl<T> IntoEither for T
impl<T> IntoEither for T
Sourceยงfn into_either(self, into_left: bool) -> Either<Self, Self> โ
fn into_either(self, into_left: bool) -> Either<Self, Self> โ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSourceยงfn into_either_with<F>(self, into_left: F) -> Either<Self, Self> โ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> โ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreยงimpl<T, I> IntoReactiveValue<T, __IntoReactiveValueMarkerBaseCase> for Iwhere
I: Into<T>,
impl<T, I> IntoReactiveValue<T, __IntoReactiveValueMarkerBaseCase> for Iwhere
I: Into<T>,
ยงfn into_reactive_value(self) -> T
fn into_reactive_value(self) -> T
self into a T.Sourceยงimpl<T> IntoStimulus<T> for T
impl<T> IntoStimulus<T> for T
Sourceยงfn into_stimulus(self) -> T
fn into_stimulus(self) -> T
self into T, while performing the appropriate scaling,
rounding and clamping.ยงimpl<T> Pointable for T
impl<T> Pointable for T
ยงimpl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Sourceยงimpl<R> Rng for R
impl<R> Rng for R
Sourceยงfn random<T>(&mut self) -> Twhere
StandardUniform: Distribution<T>,
fn random<T>(&mut self) -> Twhere
StandardUniform: Distribution<T>,
StandardUniform distribution. Read moreSourceยงfn random_iter<T>(self) -> Iter<StandardUniform, Self, T> โ
fn random_iter<T>(self) -> Iter<StandardUniform, Self, T> โ
Sourceยงfn random_range<T, R>(&mut self, range: R) -> Twhere
T: SampleUniform,
R: SampleRange<T>,
fn random_range<T, R>(&mut self, range: R) -> Twhere
T: SampleUniform,
R: SampleRange<T>,
Sourceยงfn random_bool(&mut self, p: f64) -> bool
fn random_bool(&mut self, p: f64) -> bool
p of being true. Read moreSourceยงfn random_ratio(&mut self, numerator: u32, denominator: u32) -> bool
fn random_ratio(&mut self, numerator: u32, denominator: u32) -> bool
numerator/denominator of being
true. Read moreSourceยงfn sample<T, D>(&mut self, distr: D) -> Twhere
D: Distribution<T>,
fn sample<T, D>(&mut self, distr: D) -> Twhere
D: Distribution<T>,
Sourceยงfn sample_iter<T, D>(self, distr: D) -> Iter<D, Self, T> โwhere
D: Distribution<T>,
Self: Sized,
fn sample_iter<T, D>(self, distr: D) -> Iter<D, Self, T> โwhere
D: Distribution<T>,
Self: Sized,
Sourceยงfn gen<T>(&mut self) -> Twhere
StandardUniform: Distribution<T>,
fn gen<T>(&mut self) -> Twhere
StandardUniform: Distribution<T>,
random to avoid conflict with the new gen keyword in Rust 2024.Rng::random.Sourceยงfn gen_range<T, R>(&mut self, range: R) -> Twhere
T: SampleUniform,
R: SampleRange<T>,
fn gen_range<T, R>(&mut self, range: R) -> Twhere
T: SampleUniform,
R: SampleRange<T>,
random_rangeRng::random_range.ยงimpl<T> SerializableKey for T
impl<T> SerializableKey for T
ยงimpl<T> StorageAccess<T> for T
impl<T> StorageAccess<T> for T
ยงfn as_borrowed(&self) -> &T
fn as_borrowed(&self) -> &T
ยงfn into_taken(self) -> T
fn into_taken(self) -> T
Sourceยงimpl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
Sourceยงtype Error = <C as TryFromComponents<T>>::Error
type Error = <C as TryFromComponents<T>>::Error
try_into_colors fails to cast.Sourceยงfn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
Sourceยงimpl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
Sourceยงfn try_into_color(self) -> Result<U, OutOfBounds<U>>
fn try_into_color(self) -> Result<U, OutOfBounds<U>>
OutOfBounds error is returned which contains
the unclamped color. Read moreSourceยงimpl<R> TryRngCore for R
impl<R> TryRngCore for R
Sourceยงtype Error = Infallible
type Error = Infallible
Sourceยงfn try_next_u32(&mut self) -> Result<u32, <R as TryRngCore>::Error>
fn try_next_u32(&mut self) -> Result<u32, <R as TryRngCore>::Error>
u32.Sourceยงfn try_next_u64(&mut self) -> Result<u64, <R as TryRngCore>::Error>
fn try_next_u64(&mut self) -> Result<u64, <R as TryRngCore>::Error>
u64.Sourceยงfn try_fill_bytes(
&mut self,
dst: &mut [u8],
) -> Result<(), <R as TryRngCore>::Error>
fn try_fill_bytes( &mut self, dst: &mut [u8], ) -> Result<(), <R as TryRngCore>::Error>
dest entirely with random data.Sourceยงfn unwrap_err(self) -> UnwrapErr<Self>where
Self: Sized,
fn unwrap_err(self) -> UnwrapErr<Self>where
Self: Sized,
UnwrapErr wrapper.Sourceยงfn unwrap_mut(&mut self) -> UnwrapMut<'_, Self>
fn unwrap_mut(&mut self) -> UnwrapMut<'_, Self>
UnwrapMut wrapper.Sourceยงfn read_adapter(&mut self) -> RngReadAdapter<'_, Self>where
Self: Sized,
fn read_adapter(&mut self) -> RngReadAdapter<'_, Self>where
Self: Sized,
std only.RngCore to a RngReadAdapter.