DEV Community

Syeed Talha
Syeed Talha

Posted on

Beginner’s Guide to Axum: Path, Query & JSON

If you're starting backend development in Rust, Axum is a great choice.

In this guide, we will build a small API and learn:

  • ✅ Path Parameters
  • ✅ Query Parameters
  • ✅ JSON Request & Response

And most importantly: you’ll get the FULL working code at the end.


What We Are Building

We will create 3 routes:

Route Method Description
/user/:name/:id/:age GET Path parameters
/search?name=...&age=... GET Query parameters
/user POST JSON request

Required Dependencies

We use serde for converting data.

Add this to your Cargo.toml:

[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
Enter fullscreen mode Exit fullscreen mode

1. Path Parameters

Example URL

/user/talha/10/22
Enter fullscreen mode Exit fullscreen mode

👉 Here:

  • name = talha
  • id = 10
  • age = 22

Code

async fn get_user(Path((name, id, age)): Path<(String, i32, i32)>) -> String {
    format!("User Name is: {}\n, age: {}\n and Id is {}", name, age, id)
}
Enter fullscreen mode Exit fullscreen mode

Axum extracts values directly from the URL.


2. Query Parameters

Example URL

/search?name=talha&age=22
Enter fullscreen mode Exit fullscreen mode

Struct

#[derive(Deserialize)]
struct SearchParams {
    name: String,
    age: i32,
}
Enter fullscreen mode Exit fullscreen mode

Code

async fn search(Query(params): Query<SearchParams>) -> String {
    format!("User name is {} and he is now {} years old", params.name, params.age)
}
Enter fullscreen mode Exit fullscreen mode

Axum converts query into a struct automatically.


3. JSON Request & Response (POST)

Request JSON

{
  "name": "Talha",
  "age": 22
}
Enter fullscreen mode Exit fullscreen mode

Structs

#[derive(Deserialize)]
struct CreateUser {
    name: String,
    age: i32,
}

#[derive(Serialize)]
struct UserResponse {
    message: String,
}
Enter fullscreen mode Exit fullscreen mode

Code

async fn create_user(Json(payload): Json<CreateUser>) -> Json<UserResponse> {
    let msg = format!("User {} is {} years old", payload.name, payload.age);

    Json(UserResponse {
        message: msg,
    })
}
Enter fullscreen mode Exit fullscreen mode

Full Working Code (Copy & Run)

This is the complete code you can copy and run directly:

use axum::{
    routing::{get, post},
    Router,
    extract::{Path, Query, Json},
};
use serde::{Deserialize, Serialize};

#[derive(Deserialize)]
struct SearchParams {
    name: String,
    age: i32,
}

#[derive(Deserialize)]
struct CreateUser {
    name: String,
    age: i32,
}

#[derive(Serialize)]
struct UserResponse {
    message: String,
}

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/user/:name/:id/:age", get(get_user))
        .route("/search", get(search))
        .route("/user", post(create_user));

    let addr = "127.0.0.1:3000";
    println!("Server running on http://{}", addr);

    axum::serve(
        tokio::net::TcpListener::bind(addr).await.unwrap(),
        app,
    )
    .await
    .unwrap();
}

async fn get_user(Path((name, id, age)): Path<(String, i32, i32)>) -> String {
    format!("User Name is: {}\n, age: {}\n and Id is {}", name, age, id)
}

async fn search(Query(params): Query<SearchParams>) -> String {
    format!(
        "User name is {} and he is now {} years old",
        params.name, params.age
    )
}

async fn create_user(Json(payload): Json<CreateUser>) -> Json<UserResponse> {
    let msg = format!("User {} is {} years old", payload.name, payload.age);

    Json(UserResponse {
        message: msg,
    })
}
Enter fullscreen mode Exit fullscreen mode

How to Run

cargo run
Enter fullscreen mode Exit fullscreen mode

Then test in browser or Postman:


Test Path

http://localhost:3000/user/talha/10/22
Enter fullscreen mode Exit fullscreen mode

Test Query

http://localhost:3000/search?name=talha&age=22
Enter fullscreen mode Exit fullscreen mode

Test POST (Important)

Use Postman / curl:

curl -X POST http://localhost:3000/user \
-H "Content-Type: application/json" \
-d '{"name":"Talha","age":22}'
Enter fullscreen mode Exit fullscreen mode

What You Learned

✔ Path parameters → Path<T>
✔ Query parameters → Query<T>
✔ JSON body → Json<T>
✔ Structs + Serde = powerful API


Top comments (0)