Function axum::middleware::map_response

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

Create a middleware from an async function that transforms a response.

This differs from tower::util::MapResponse in that it allows you to easily run axum-specific extractors.

Example

use axum::{
    Router,
    routing::get,
    middleware::map_response,
    response::Response,
};

async fn set_header<B>(mut response: Response<B>) -> Response<B> {
    response.headers_mut().insert("x-foo", "foo".parse().unwrap());
    response
}

let app = Router::new()
    .route("/", get(|| async { /* ... */ }))
    .layer(map_response(set_header));

Running extractors

It is also possible to run extractors that implement FromRequestParts. These will be run before calling the handler.

use axum::{
    Router,
    routing::get,
    middleware::map_response,
    extract::Path,
    response::Response,
};
use std::collections::HashMap;

async fn log_path_params<B>(
    Path(path_params): Path<HashMap<String, String>>,
    response: Response<B>,
) -> Response<B> {
    tracing::debug!(?path_params);
    response
}

let app = Router::new()
    .route("/", get(|| async { /* ... */ }))
    .layer(map_response(log_path_params));

Note that to access state you must use either map_response_with_state.

Returning any impl IntoResponse

It is also possible to return anything that implements IntoResponse

use axum::{
    Router,
    routing::get,
    middleware::map_response,
    response::{Response, IntoResponse},
};
use std::collections::HashMap;

async fn set_header(response: Response) -> impl IntoResponse {
    (
        [("x-foo", "foo")],
        response,
    )
}

let app = Router::new()
    .route("/", get(|| async { /* ... */ }))
    .layer(map_response(set_header));