name: axum description: Axum Rust web framework expert. Auto-loads when working with axum Router, handlers, extractors, FromRequest, IntoResponse, State, middleware, tower layers, tower-http, axum::serve, method routing, Json extractor, Path extractor, Query extractor, error handling, or Rust HTTP APIs. Keywords: axum, router, handler, extractor, middleware, tower, IntoResponse, FromRequest, State, Rust web, HTTP API
Axum
Axum is an ergonomic, modular Rust web framework built on Tokio, Hyper, and Tower. It uses extractors (no macros) for request parsing and Tower services/layers for middleware.
Quick Start
use axum::{routing::get, Router};
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(|| async { "Hello, World!" }));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
Core Architecture
- Router — maps paths to handlers/services; supports nesting, merging, fallbacks, layers
- Handlers — async fns taking extractors and returning
impl IntoResponse - Extractors — types implementing
FromRequest/FromRequestPartsthat parse requests - Responses — any type implementing
IntoResponse(String, Json, StatusCode, tuples...) - Middleware — Tower layers applied via
Router::layer()ormiddleware::from_fn - State — shared app state via
State<T>extractor with.with_state()
Handler Pattern
async fn create_user(
State(db): State<Pool>, // FromRequestParts (any position)
Path(id): Path<u32>, // FromRequestParts (any position)
Json(payload): Json<CreateUser>, // FromRequest (must be LAST)
) -> Result<Json<User>, StatusCode> {
// ...
}
Rules: up to 16 args, all FromRequestParts except last which can be FromRequest (body).
Common Extractors
| Extractor | Trait | Purpose |
|---|---|---|
Path<T> |
Parts | Deserialize path params |
Query<T> |
Parts | Deserialize query string |
State<T> |
Parts | Access shared app state |
HeaderMap |
Parts | All request headers |
Json<T> |
Request | Deserialize JSON body |
Form<T> |
Request | Deserialize form body |
String / Bytes |
Request | Raw body content |
Routing
Router::new()
.route("/users", get(list_users).post(create_user))
.route("/users/{id}", get(get_user).put(update_user).delete(delete_user))
.nest("/api", api_router)
.merge(other_router)
.fallback(handler_404)
.layer(tower_http::trace::TraceLayer::new_for_http())
.with_state(app_state)
Error Pattern
enum AppError { NotFound, Internal(anyhow::Error) }
impl IntoResponse for AppError {
fn into_response(self) -> Response {
match self {
AppError::NotFound => StatusCode::NOT_FOUND.into_response(),
AppError::Internal(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()).into_response(),
}
}
}
async fn handler() -> Result<Json<Data>, AppError> {
let data = fetch().map_err(AppError::Internal)?;
Ok(Json(data))
}
Key Dependencies
[dependencies]
axum = "0.8"
tokio = { version = "1", features = ["full"] }
tower = "0.5"
tower-http = { version = "0.6", features = ["cors", "trace", "compression-gzip"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
References
- Routing — Router, method routing, path params, nesting, merging, fallback, layers
- Handlers — Handler trait, signatures, requirements, closures, debug_handler
- Extractors — all built-in extractors, ordering rules, optional, custom extractors
- Responses — IntoResponse, IntoResponseParts, tuples, custom responses
- State Management — State extractor, Extension, closures, task-local patterns
- Middleware — from_fn, from_extractor, Tower layers, execution order
- Error Handling — error model, Result pattern, rejections, HandleError
- Tower-HTTP — CORS, tracing, compression, timeout, catch-panic, request-id