Skip to main content
Axum provides built-in extractors for common HTTP request components. These extractors implement FromRequestParts and can be freely combined with other extractors.

Request

Extract the entire request, consuming it:
use axum::extract::Request;

async fn handler(request: Request) {
    // Access the full request
    let method = request.method();
    let uri = request.uri();
    let headers = request.headers();
    let body = request.into_body();
}
Request
http::Request<Body>
The entire HTTP request.

Method

Extract the HTTP method:
use http::Method;

async fn handler(method: Method) {
    match method {
        Method::GET => { /* ... */ }
        Method::POST => { /* ... */ }
        _ => { /* ... */ }
    }
}
Method
http::Method
The HTTP method (GET, POST, PUT, DELETE, etc.).

Uri

Extract the request URI:
use http::Uri;

async fn handler(uri: Uri) {
    let path = uri.path();
    let query = uri.query();
    
    println!("Request path: {}", path);
    if let Some(query) = query {
        println!("Query string: {}", query);
    }
}
Uri
http::Uri
The request URI, including path and query string.

HeaderMap

Extract all request headers:
use http::HeaderMap;

async fn handler(headers: HeaderMap) {
    if let Some(user_agent) = headers.get("user-agent") {
        println!("User-Agent: {:?}", user_agent);
    }
    
    if let Some(auth) = headers.get("authorization") {
        // Handle authorization
    }
}
HeaderMap
http::HeaderMap
A map of all HTTP headers. The headers are cloned from the request.
Prefer using TypedHeader from axum-extra to extract only the headers you need with type safety.

Version

Extract the HTTP version:
use http::Version;

async fn handler(version: Version) {
    match version {
        Version::HTTP_09 => { /* ... */ }
        Version::HTTP_10 => { /* ... */ }
        Version::HTTP_11 => { /* ... */ }
        Version::HTTP_2 => { /* ... */ }
        Version::HTTP_3 => { /* ... */ }
        _ => { /* ... */ }
    }
}
Version
http::Version
The HTTP version (HTTP/1.1, HTTP/2, HTTP/3, etc.).

Extension

Extract typed values from request extensions:
use axum::Extension;

#[derive(Clone)]
struct CurrentUser {
    id: u64,
    name: String,
}

async fn handler(Extension(user): Extension<CurrentUser>) {
    println!("User: {} (ID: {})", user.name, user.id);
}
Extension
Extension<T>
A typed value stored in request extensions. Returns 500 Internal Server Error if the extension is not found.

Optional extensions

Use Option<Extension<T>> to make the extension optional:
async fn handler(user: Option<Extension<CurrentUser>>) {
    match user {
        Some(Extension(user)) => {
            println!("Authenticated user: {}", user.name);
        }
        None => {
            println!("Anonymous request");
        }
    }
}

Adding extensions

Extensions are typically added by middleware:
use axum::{
    Router,
    Extension,
    routing::get,
};

#[derive(Clone)]
struct MyExtension {
    value: String,
}

let app = Router::new()
    .route("/", get(handler))
    .layer(Extension(MyExtension { 
        value: "shared data".to_owned() 
    }));

async fn handler(Extension(ext): Extension<MyExtension>) {
    println!("Extension value: {}", ext.value);
}

Parts

Extract the entire request parts (everything except the body):
use http::request::Parts;

async fn handler(parts: Parts) {
    let method = parts.method;
    let uri = parts.uri;
    let headers = parts.headers;
    let version = parts.version;
    let extensions = parts.extensions;
}
Parts
http::request::Parts
All parts of the request except the body. The parts are cloned.

Extensions

Extract the raw extensions map:
use http::Extensions;

async fn handler(extensions: Extensions) {
    if let Some(user) = extensions.get::<CurrentUser>() {
        println!("User ID: {}", user.id);
    }
}
Extensions
http::Extensions
The raw type map of request extensions. The extensions are cloned.

Body extractors

These extractors consume the request body:

String

async fn handler(body: String) {
    println!("Request body: {}", body);
}
String
String
The entire request body as a UTF-8 string. Returns 400 Bad Request if the body is not valid UTF-8.

Bytes

use bytes::Bytes;

async fn handler(body: Bytes) {
    println!("Body length: {} bytes", body.len());
}
Bytes
bytes::Bytes
The entire request body as raw bytes.

Body

use axum::body::Body;

async fn handler(body: Body) {
    // Stream the body
}
Body
axum::body::Body
The raw request body as a stream.
Body extractors consume the request body and must be placed last in the handler parameters. See the order of extractors.

Combining extractors

You can combine multiple request part extractors in a single handler:
use http::{Method, Uri, HeaderMap};

async fn handler(
    method: Method,
    uri: Uri,
    headers: HeaderMap,
    body: String,
) {
    println!("{} {} HTTP/1.1", method, uri.path());
    println!("Headers: {} headers", headers.len());
    println!("Body: {}", body);
}