From 4fd7e927bad361f3cdfd561f56721184c952d8ee Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Mon, 27 Dec 2021 23:53:50 +0100 Subject: [PATCH] Document how to pass state to `middleware::from_fn` (#669) --- axum-extra/src/middleware/middleware_fn.rs | 75 +++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/axum-extra/src/middleware/middleware_fn.rs b/axum-extra/src/middleware/middleware_fn.rs index 6ffc05b9..0a0a9fe4 100644 --- a/axum-extra/src/middleware/middleware_fn.rs +++ b/axum-extra/src/middleware/middleware_fn.rs @@ -27,7 +27,7 @@ use tower_service::Service; /// `from_fn` requires the function given to /// /// 1. Be an `async fn`. -/// 2. Take [`Request`](http::Request) as the first argument. +/// 2. Take [`Request`](http::Request) as the first argument. /// 3. Take [`Next`](Next) as the second argument. /// 4. Return something that implements [`IntoResponse`]. /// @@ -65,6 +65,79 @@ use tower_service::Service; /// .route_layer(middleware::from_fn(auth)); /// # let app: Router = app; /// ``` +/// +/// # Passing state +/// +/// State can be passed to the function like so: +/// +/// ```rust +/// use axum::{ +/// Router, +/// http::{Request, StatusCode}, +/// routing::get, +/// response::IntoResponse, +/// }; +/// use axum_extra::middleware::{self, Next}; +/// +/// #[derive(Clone)] +/// struct State { /* ... */ } +/// +/// async fn my_middleware( +/// req: Request, +/// next: Next, +/// state: State, +/// ) -> impl IntoResponse { +/// // ... +/// # () +/// } +/// +/// let state = State { /* ... */ }; +/// +/// let app = Router::new() +/// .route("/", get(|| async { /* ... */ })) +/// .route_layer(middleware::from_fn(move |req, next| { +/// my_middleware(req, next, state.clone()) +/// })); +/// # let app: Router = app; +/// ``` +/// +/// Or via extensions: +/// +/// ```rust +/// use axum::{ +/// Router, +/// http::{Request, StatusCode}, +/// routing::get, +/// response::IntoResponse, +/// AddExtensionLayer, +/// }; +/// use axum_extra::middleware::{self, Next}; +/// use tower::ServiceBuilder; +/// +/// #[derive(Clone)] +/// struct State { /* ... */ } +/// +/// async fn my_middleware( +/// req: Request, +/// next: Next, +/// ) -> impl IntoResponse { +/// let state: &State = req.extensions().get().unwrap(); +/// +/// // ... +/// # () +/// } +/// +/// let state = State { /* ... */ }; +/// +/// let app = Router::new() +/// .route("/", get(|| async { /* ... */ })) +/// .layer( +/// ServiceBuilder::new() +/// .layer(AddExtensionLayer::new(state)) +/// .layer(middleware::from_fn(my_middleware)), +/// ); +/// # let app: Router = app; +/// ``` pub fn from_fn(f: F) -> MiddlewareFnLayer { MiddlewareFnLayer { f } }