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.
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.