Struct axum::extract::State

source ·
pub struct State<S>(pub S);
Expand description

Extractor for state.

See “Accessing state in middleware” for how to access state in middleware.

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
//
// see "When states need to implement `Clone`" for more details on why we need
// `#[derive(Clone)]` here.
#[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`...
}

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);

axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
    .serve(handler_with_state.into_make_service())
    .await
    .expect("server failed");

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 async_trait::async_trait;
use std::convert::Infallible;

// the extractor your library provides
struct MyLibraryExtractor;

#[async_trait]
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 {
    // ...
}

When states need to implement Clone

Your top level state type must implement Clone to be extractable with State:

use axum::extract::State;

// no substates, so to extract to `State<AppState>` we must implement `Clone` for `AppState`
#[derive(Clone)]
struct AppState {}

async fn handler(State(state): State<AppState>) {
    // ...
}

This works because of impl<S> FromRef<S> for S where S: Clone.

This is also true if you’re extracting substates, unless you never extract the top level state itself:

use axum::extract::{State, FromRef};

// we never extract `State<AppState>`, just `State<InnerState>`. So `AppState` doesn't need to
// implement `Clone`
struct AppState {
    inner: InnerState,
}

#[derive(Clone)]
struct InnerState {}

impl FromRef<AppState> for InnerState {
    fn from_ref(app_state: &AppState) -> InnerState {
        app_state.inner.clone()
    }
}

async fn api_users(State(inner): State<InnerState>) {
    // ...
}

In general however we recommend you implement Clone for all your state types to avoid potential type errors.

Tuple Fields§

§0: S

Trait Implementations§

source§

impl<S: Clone> Clone for State<S>

source§

fn clone(&self) -> State<S>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<S: Debug> Debug for State<S>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<S: Default> Default for State<S>

source§

fn default() -> State<S>

Returns the “default value” for a type. Read more
source§

impl<S> Deref for State<S>

§

type Target = S

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<S> DerefMut for State<S>

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl<OuterState, InnerState> FromRequestParts<OuterState> for State<InnerState>where InnerState: FromRef<OuterState>, OuterState: Send + Sync,

§

type Rejection = Infallible

If the extractor fails it’ll use this “rejection” type. A rejection is a kind of error that can be converted into a response.
source§

fn from_request_parts<'life0, 'life1, 'async_trait>( _parts: &'life0 mut Parts, state: &'life1 OuterState ) -> Pin<Box<dyn Future<Output = Result<Self, Self::Rejection>> + Send + 'async_trait>>where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Perform the extraction.
source§

impl<S: Copy> Copy for State<S>

Auto Trait Implementations§

§

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§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> FromRef<T> for Twhere T: Clone,

source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
source§

impl<S, B, T> FromRequest<S, B, ViaParts> for Twhere B: Send + 'static, S: Send + Sync, T: FromRequestParts<S>,

§

type Rejection = <T as FromRequestParts<S>>::Rejection

If the extractor fails it’ll use this “rejection” type. A rejection is a kind of error that can be converted into a response.
source§

fn from_request<'life0, 'async_trait>( req: Request<B>, state: &'life0 S ) -> Pin<Box<dyn Future<Output = Result<T, <T as FromRequest<S, B, ViaParts>>::Rejection>> + Send + 'async_trait, Global>>where 'life0: 'async_trait, T: 'async_trait,

Perform the extraction.
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> PolicyExt for Twhere T: ?Sized,

source§

fn and<P, B, E>(self, other: P) -> And<T, P>where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
source§

fn or<P, B, E>(self, other: P) -> Or<T, P>where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more