JSON Body dengan Serde
Penjelasan
Untuk endpoint yang menerima data JSON di body request (biasanya POST/PUT), Axum menyediakan extractor `Json<T>`. Sama seperti `Query<T>`, extractor ini memakai Serde untuk mem-parsing body JSON menjadi struct Rust — kamu cukup mendefinisikan struct dengan `#[derive(Deserialize)]`. Axum otomatis memvalidasi bahwa `Content-Type` request adalah `application/json` dan body-nya valid JSON sesuai struct target. Kalau tidak, handler tidak akan dipanggil sama sekali — Axum langsung mengembalikan 415 (Unsupported Media Type) atau 400 (Bad Request) tergantung jenis kesalahannya. Penting: `Json<T>` mengonsumsi body request, jadi hanya boleh ada satu extractor body per handler. Kalau kamu butuh beberapa sumber data sekaligus (path + body misalnya), urutan parameter di signature handler ikut aturan tertentu yang akan dibahas di topik Urutan Extractor.
Contoh Konsep
use axum::{routing::post, Json, Router};
use serde::Deserialize;
#[derive(Deserialize)]
struct CreateNote {
title: String,
body: String,
}
async fn create_note(Json(payload): Json<CreateNote>) -> String {
format!("Catatan '{}' berhasil dibuat", payload.title)
}
#[tokio::main]
async fn main() {
let app = Router::new().route("/notes", post(create_note));
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
// curl -X POST http://127.0.0.1:3000/notes \
// -H "Content-Type: application/json" \
// -d '{"title":"Belajar Axum","body":"Extractor itu keren"}'
Praktikum
Buat struct `LoginRequest` dengan field `username` dan `password` (keduanya `String`), lalu buat handler `login` yang menerima `Json<LoginRequest>` dan mengembalikan pesan selamat datang berisi username.
Ketik/edit bebas di sini untuk latihan — kode ini tidak dijalankan.
Tips
Jangan lupa tambahkan crate `serde` dengan feature `derive` (`cargo add serde --features derive`) dan `serde_json` di `Cargo.toml` — keduanya bukan bawaan Axum, tapi selalu dipakai bersamaan karena `Json<T>` bergantung penuh pada Serde.