Study
Axum

Membangun Response JSON

Penjelasan

Handler Axum bisa mengembalikan tipe apa pun asalkan tipe itu meng-implementasi trait `IntoResponse` — inilah mekanisme yang membuat `"Hello"` (yang meng-implementasi `IntoResponse` untuk `&str`), `Json<T>`, `StatusCode`, bahkan tuple seperti `(StatusCode, Json<T>)` semuanya bisa langsung jadi nilai balik handler. Untuk response JSON, cara paling umum adalah membungkus struct yang meng-implementasi `Serialize` ke dalam `Json(...)`. Kalau kamu ingin mengontrol status code sekaligus (misalnya 201 Created untuk resource baru), kembalikan tuple `(StatusCode, Json<T>)` — Axum tahu cara menggabungkan keduanya menjadi satu response HTTP yang valid. Pola ini konsisten di seluruh Axum: bukan hanya `String` dan `Json`, tapi hampir semua tipe response HTTP (header, redirect, file) mengikuti aturan `IntoResponse` yang sama, jadi begitu kamu paham konsepnya, kamu bisa mengombinasikan berbagai jenis response dengan cara yang sama.

Contoh Konsep

use axum::{http::StatusCode, routing::get, Json, Router};
use serde::Serialize;

#[derive(Serialize)]
struct Note {
    id: u32,
    title: String,
}

async fn get_note() -> Json<Note> {
    Json(Note { id: 1, title: "Belajar Axum".to_string() })
}

async fn create_note() -> (StatusCode, Json<Note>) {
    let note = Note { id: 2, title: "Catatan baru".to_string() };
    // 201 Created bersama body JSON
    (StatusCode::CREATED, Json(note))
}

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/notes/1", get(get_note))
        .route("/notes", axum::routing::post(create_note));

    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

Praktikum

Buat struct `User` dengan field `id: u32` dan `name: String` yang bisa di-serialize, lalu buat handler `get_user` yang mengembalikan `Json<User>` berisi data user dummy.

Editor Latihan

Ketik/edit bebas di sini untuk latihan — kode ini tidak dijalankan.

Tips

Kalau kamu punya banyak handler yang mengembalikan tuple `(StatusCode, Json<T>)` dengan status code sama berulang-ulang, pertimbangkan membuat helper function kecil supaya tidak menulis `StatusCode::CREATED` di banyak tempat — ini juga mempermudah kalau nanti kamu ingin menambahkan header tambahan secara konsisten.