Function axum::extract::extractor_middleware[][src]

pub fn extractor_middleware<E>() -> ExtractorMiddlewareLayer<E>
Expand description

Convert an extractor into a middleware.

If the extractor succeeds the value will be discarded and the inner service will be called. If the extractor fails the rejection will be returned and the inner service will not be called.

This can be used to perform validation of requests if the validation doesn’t produce any useful output, and run the extractor for several handlers without repeating it in the function signature.

Note that if the extractor consumes the request body, as String or Bytes does, an empty body will be left in its place. Thus wont be accessible to subsequent extractors or handlers.

Example

use axum::{
    extract::{extractor_middleware, FromRequest, RequestParts},
    handler::{get, post},
    Router,
};
use http::StatusCode;
use async_trait::async_trait;

// An extractor that performs authorization.
struct RequireAuth;

#[async_trait]
impl<B> FromRequest<B> for RequireAuth
where
    B: Send,
{
    type Rejection = StatusCode;

    async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
        let auth_header = req
            .headers()
            .and_then(|headers| headers.get(http::header::AUTHORIZATION))
            .and_then(|value| value.to_str().ok());

        if let Some(value) = auth_header {
            if value == "secret" {
                return Ok(Self);
            }
        }

        Err(StatusCode::UNAUTHORIZED)
    }
}

async fn handler() {
    // If we get here the request has been authorized
}

async fn other_handler() {
    // If we get here the request has been authorized
}

let app = Router::new()
    .route("/", get(handler))
    .route("/foo", post(other_handler))
    // The extractor will run before all routes
    .layer(extractor_middleware::<RequireAuth>());