Function axum::middleware::from_fn

source ·
pub fn from_fn<F, T>(f: F) -> FromFnLayer<F, (), T>
Expand description

Create a middleware from an async function.

from_fn requires the function given to

  1. Be an async fn.
  2. Take one or more extractors as the first arguments.
  3. Take Next<B> as the final argument.
  4. Return something that implements IntoResponse.

Example

use axum::{
    Router,
    http::{Request, StatusCode},
    routing::get,
    response::{IntoResponse, Response},
    middleware::{self, Next},
};

async fn auth<B>(req: Request<B>, next: Next<B>) -> Result<Response, StatusCode> {
    let auth_header = req.headers()
        .get(http::header::AUTHORIZATION)
        .and_then(|header| header.to_str().ok());

    match auth_header {
        Some(auth_header) if token_is_valid(auth_header) => {
            Ok(next.run(req).await)
        }
        _ => Err(StatusCode::UNAUTHORIZED),
    }
}

fn token_is_valid(token: &str) -> bool {
    // ...
}

let app = Router::new()
    .route("/", get(|| async { /* ... */ }))
    .route_layer(middleware::from_fn(auth));

Running extractors

use axum::{
    Router,
    extract::{TypedHeader, Query},
    headers::authorization::{Authorization, Bearer},
    http::Request,
    middleware::{self, Next},
    response::Response,
    routing::get,
};
use std::collections::HashMap;

async fn my_middleware<B>(
    TypedHeader(auth): TypedHeader<Authorization<Bearer>>,
    Query(query_params): Query<HashMap<String, String>>,
    // you can add more extractors here but the last
    // extractor must implement `FromRequest` which
    // `Request` does
    req: Request<B>,
    next: Next<B>,
) -> Response {
    // do something with `auth` and `query_params`...

    next.run(req).await
}

let app = Router::new()
    .route("/", get(|| async { /* ... */ }))
    .route_layer(middleware::from_fn(my_middleware));