Introduction
Axum is an ergonomic and modular web framework built with Tokio, Tower, and Hyper. It's designed to be easy to use while retaining high performance.
High Level Features
Axum stands out with its clean, macro-free API and strong ecosystem integration:
Macro-free API: Route requests to handlers without complex macros.
Extractors: Declaratively parse requests (JSON, Query, Path) using function signatures.
Tower Ecosystem: Takes full advantage of [tower](https://crates.io/crates/tower) and [tower-http](https://crates.io/crates/tower-http) for middleware, services, and utilities.
Safe Rust: implemented with #![forbid(unsafe_code)] for 100% safe Rust.
Getting Started
First, create a new project and add dependencies:
$cargo new my-axum-app$cd my-axum-app$cargo add axum tokio serde serde_json tracing tracing-subscriber
Basic Usage
Here is a simple example showing routing, JSON handling, and starting the server using valid Axum 0.7+ syntax:
use axum::{routing::{get, post},http::StatusCode,Json, Router,};use serde::{Deserialize, Serialize};#[tokio::main]async fn main() {// initialize tracingtracing_subscriber::fmt::init();// build our application with a routelet app = Router::new().route("/", get(root)).route("/users", post(create_user));// run our app with hyper, listening globally on port 3000let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();println!("Listening on {}", listener.local_addr().unwrap());axum::serve(listener, app).await.unwrap();}// basic handler that responds with a static stringasync fn root() -> &'static str {"Hello, World!"}async fn create_user(// this argument tells axum to parse the request body// as JSON into a `CreateUser` typeJson(payload): Json<CreateUser>,) -> (StatusCode, Json<User>) {// insert your application logic herelet user = User {id: 1337,username: payload.username,};// this will be converted into a JSON response// with a status code of `201 Created`(StatusCode::CREATED, Json(user))}// the input to our `create_user` handler#[derive(Deserialize)]struct CreateUser {username: String,}// the output to our `create_user` handler#[derive(Serialize)]struct User {id: u64,username: String,}
Why Choose Axum?
1. Performance
Axum is a relatively thin layer on top of Hyper, adding very little overhead. Its performance is comparable to Hyper directly, making it one of the fastest web frameworks available.
2. Ecosystem
Because it implements tower::Service, you get access to a massive ecosystem of middleware for timeout, tracing, compression, and authorization "for free".
3. Reliability
Axum's strict type system and "fearless concurrency" via Rust ensure that many classes of bugs are caught at compile time.
Conclusion
If you are building a backend in Rust, Axum provides the best balance of ergonomics, performance, and ecosystem support today.
