> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/tokio-rs/axum/llms.txt
> Use this file to discover all available pages before exploring further.

# middleware::from_fn

> Create middleware from async functions with request/response handling

The `from_fn` module provides a simple way to create middleware from async functions, allowing you to intercept and modify requests before they reach handlers and responses before they're returned to clients.

## Core functions

### from\_fn

```rust theme={null}
pub fn from_fn<F, T>(f: F) -> FromFnLayer<F, (), T>
```

Create a middleware from an async function without state access.

**Requirements:**

1. Must be an `async fn`
2. Take zero or more `FromRequestParts` extractors
3. Take exactly one `FromRequest` extractor as the second to last argument
4. Take `Next` as the last argument
5. Return something that implements `IntoResponse`

**Basic example:**

```rust theme={null}
use axum::{
    Router,
    routing::get,
    response::Response,
    middleware::{self, Next},
    extract::Request,
};

async fn my_middleware(
    request: Request,
    next: Next,
) -> Response {
    // Process request before handler
    let response = next.run(request).await;
    // Process response after handler
    response
}

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

### from\_fn\_with\_state

```rust theme={null}
pub fn from_fn_with_state<F, S, T>(state: S, f: F) -> FromFnLayer<F, S, T>
```

Create a middleware from an async function with state access.

**Example with state:**

```rust theme={null}
use axum::{
    Router,
    routing::get,
    response::Response,
    middleware::{self, Next},
    extract::{Request, State},
};

#[derive(Clone)]
struct AppState { /* ... */ }

async fn my_middleware(
    State(state): State<AppState>,
    request: Request,
    next: Next,
) -> Response {
    // Access state in middleware
    let response = next.run(request).await;
    response
}

let state = AppState { /* ... */ };

let app = Router::new()
    .route("/", get(|| async { /* ... */ }))
    .route_layer(middleware::from_fn_with_state(state.clone(), my_middleware))
    .with_state(state);
```

## Request/response handling patterns

### Modifying requests

Insert headers or modify the request before it reaches handlers:

```rust theme={null}
use axum::{
    extract::Request,
    middleware::Next,
    response::IntoResponse,
};

async fn insert_header(mut req: Request, next: Next) -> impl IntoResponse {
    req.headers_mut()
        .insert("x-custom-header", "value".parse().unwrap());
    
    next.run(req).await
}
```

### Processing request body

Consume and inspect the request body:

```rust theme={null}
use axum::{
    body::{Body, Bytes},
    extract::Request,
    http::StatusCode,
    middleware::Next,
    response::{IntoResponse, Response},
};
use http_body_util::BodyExt;

async fn print_request_body(
    request: Request,
    next: Next,
) -> Result<impl IntoResponse, Response> {
    let (parts, body) = request.into_parts();
    
    // Collect the body bytes
    let bytes = body
        .collect()
        .await
        .map_err(|err| {
            (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response()
        })?
        .to_bytes();
    
    // Process the bytes
    tracing::debug!("Request body: {:?}", bytes);
    
    // Reconstruct request with buffered body
    let req = Request::from_parts(parts, Body::from(bytes));
    
    Ok(next.run(req).await)
}
```

### Processing request and response

Handle both request and response in the same middleware:

```rust theme={null}
use axum::{
    body::{Body, Bytes},
    extract::Request,
    http::StatusCode,
    middleware::Next,
    response::{IntoResponse, Response},
};
use http_body_util::BodyExt;

async fn print_request_response(
    req: Request,
    next: Next,
) -> Result<impl IntoResponse, (StatusCode, String)> {
    // Process request
    let (parts, body) = req.into_parts();
    let bytes = body.collect().await
        .map_err(|e| (StatusCode::BAD_REQUEST, e.to_string()))?
        .to_bytes();
    
    tracing::debug!("request body = {:?}", std::str::from_utf8(&bytes));
    let req = Request::from_parts(parts, Body::from(bytes));
    
    // Call handler
    let res = next.run(req).await;
    
    // Process response
    let (parts, body) = res.into_parts();
    let bytes = body.collect().await
        .map_err(|e| (StatusCode::BAD_REQUEST, e.to_string()))?
        .to_bytes();
    
    tracing::debug!("response body = {:?}", std::str::from_utf8(&bytes));
    let res = Response::from_parts(parts, Body::from(bytes));
    
    Ok(res)
}
```

## Running extractors

Use extractors to access request data:

```rust theme={null}
use axum::{
    Router,
    extract::Request,
    http::{StatusCode, HeaderMap},
    middleware::{self, Next},
    response::Response,
    routing::get,
};

async fn auth(
    // Run the HeaderMap extractor
    headers: HeaderMap,
    // Request must be the last FromRequest extractor
    request: Request,
    next: Next,
) -> Result<Response, StatusCode> {
    match get_token(&headers) {
        Some(token) if token_is_valid(token) => {
            let response = next.run(request).await;
            Ok(response)
        }
        _ => Err(StatusCode::UNAUTHORIZED),
    }
}

fn get_token(headers: &HeaderMap) -> Option<&str> {
    // Extract token from headers
    None
}

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

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

## Passing data to handlers

Use request extensions to pass data from middleware to handlers:

```rust theme={null}
use axum::{
    Router,
    http::StatusCode,
    routing::get,
    response::{IntoResponse, Response},
    middleware::{self, Next},
    extract::{Request, Extension},
};

#[derive(Clone)]
struct CurrentUser { /* ... */ }

async fn auth(mut req: Request, next: Next) -> Result<Response, StatusCode> {
    let auth_header = req.headers()
        .get(http::header::AUTHORIZATION)
        .and_then(|header| header.to_str().ok());
    
    let auth_header = if let Some(auth_header) = auth_header {
        auth_header
    } else {
        return Err(StatusCode::UNAUTHORIZED);
    };
    
    if let Some(current_user) = authorize_current_user(auth_header).await {
        // Insert the current user into request extensions
        req.extensions_mut().insert(current_user);
        Ok(next.run(req).await)
    } else {
        Err(StatusCode::UNAUTHORIZED)
    }
}

async fn authorize_current_user(auth_token: &str) -> Option<CurrentUser> {
    // Validate and return user
    None
}

async fn handler(
    // Extract the current user set by middleware
    Extension(current_user): Extension<CurrentUser>,
) {
    // Use current_user
}

let app = Router::new()
    .route("/", get(handler))
    .route_layer(middleware::from_fn(auth));
```

## Tracking metrics

Implement request tracking and metrics:

```rust theme={null}
use axum::{
    extract::{MatchedPath, Request},
    middleware::Next,
    response::IntoResponse,
};
use std::time::Instant;

async fn track_metrics(req: Request, next: Next) -> impl IntoResponse {
    let start = Instant::now();
    let path = if let Some(matched_path) = req.extensions().get::<MatchedPath>() {
        matched_path.as_str().to_owned()
    } else {
        req.uri().path().to_owned()
    };
    let method = req.method().clone();
    
    let response = next.run(req).await;
    
    let latency = start.elapsed().as_secs_f64();
    let status = response.status().as_u16().to_string();
    
    let labels = [
        ("method", method.to_string()),
        ("path", path),
        ("status", status),
    ];
    
    metrics::counter!("http_requests_total", &labels).increment(1);
    metrics::histogram!("http_requests_duration_seconds", &labels).record(latency);
    
    response
}
```

## The Next type

```rust theme={null}
pub struct Next
```

Represents the remainder of the middleware stack, including the handler.

### Methods

#### run

```rust theme={null}
pub async fn run(mut self, req: Request) -> Response
```

Execute the remaining middleware stack and return the response.

## Types

### FromFnLayer

```rust theme={null}
pub struct FromFnLayer<F, S, T>
```

A `tower::Layer` created from an async function. Created with `from_fn` or `from_fn_with_state`.

### FromFn

```rust theme={null}
pub struct FromFn<F, S, I, T>
```

The middleware service created from an async function.

### ResponseFuture

```rust theme={null}
pub struct ResponseFuture
```

The future type returned by `FromFn`.

## See also

* [middleware overview](/api/middleware) - Introduction to axum middleware
* [tower integration](/api/middleware/tower-integration) - Using tower middleware with axum
* [extractors](/api/extractors) - Learn about request extractors
