rust 58 lines · 8 steps

Building a nested REST API router in Axum

How Axum extractors and nested Routers compose a versioned user API around shared state.

Explained by highlit
1use axum::{
2 extract::{Path, State},
3 routing::{get, post},
4 Json, Router,
5};
6use serde::{Deserialize, Serialize};
7use std::sync::Arc;
8 
9#[derive(Clone)]
10struct AppState {
11 repo: Arc<UserRepository>,
12}
13 
14#[derive(Serialize)]
15struct User {
16 id: u64,
17 name: String,
18}
19 
20#[derive(Deserialize)]
21struct CreateUser {
22 name: String,
23}
24 
25async fn list_users(State(state): State<AppState>) -> Json<Vec<User>> {
26 Json(state.repo.all().await)
27}
28 
29async fn get_user(
30 State(state): State<AppState>,
31 Path(id): Path<u64>,
32) -> Json<Option<User>> {
33 Json(state.repo.find(id).await)
34}
35 
36async fn create_user(
37 State(state): State<AppState>,
38 Json(payload): Json<CreateUser>,
39) -> Json<User> {
40 Json(state.repo.insert(payload.name).await)
41}
42 
43fn users_routes() -> Router<AppState> {
44 Router::new()
45 .route("/", get(list_users).post(create_user))
46 .route("/{id}", get(get_user))
47}
48 
49fn v1_routes() -> Router<AppState> {
50 Router::new().nest("/users", users_routes())
51}
52 
53pub fn api_router(state: AppState) -> Router {
54 Router::new()
55 .nest("/api/v1", v1_routes())
56 .route("/health", get(|| async { "ok" }))
57 .with_state(state)
58}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Handler arguments are extractors: Axum pulls state, path params, and JSON bodies straight from the function signature.
  2. 2Nesting Routers lets you compose route trees by feature and version while keeping each handler small.
  3. 3with_state injects a cloneable AppState so every handler can reach shared dependencies like a repository.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Building a nested REST API router in Axum — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code