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();
}
Method
Extract the HTTP method:
use http::Method;
async fn handler(method: Method) {
match method {
Method::GET => { /* ... */ }
Method::POST => { /* ... */ }
_ => { /* ... */ }
}
}
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);
}
}
The request URI, including path and query string.
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
}
}
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 => { /* ... */ }
_ => { /* ... */ }
}
}
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);
}
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;
}
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);
}
}
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);
}
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());
}
The entire request body as raw bytes.
Body
use axum::body::Body;
async fn handler(body: Body) {
// Stream the 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.
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);
}