Study
Axum

Urutan Extractor

Penjelasan

Extractor di Axum diproses SESUAI URUTAN kemunculannya dalam signature handler, dari kiri ke kanan. Ini penting karena beberapa extractor (seperti `Json<T>`, `String`, `Bytes`) mengonsumsi body request — begitu dikonsumsi, tidak ada lagi body tersisa untuk extractor lain di belakangnya. Aturan praktisnya: extractor yang MENGONSUMSI BODY (seperti `Json<T>`) harus ditempatkan PALING TERAKHIR dalam signature handler. Extractor yang tidak menyentuh body (`Path<T>`, `Query<T>`, `State<T>`, `HeaderMap`) boleh berada di posisi mana saja sebelum extractor body. Kalau kamu melanggar aturan ini (misalnya `Json<T>` diikuti `Path<T>` di belakangnya), kompilasi akan gagal dengan pesan error yang menyebut trait `FromRequest` tidak terpenuhi untuk kombinasi tersebut — pesan errornya tidak selalu jelas, jadi mengingat aturan urutan ini akan menghemat banyak waktu debugging.

Contoh Konsep

use axum::{extract::{Path, State}, routing::put, Json, Router};
use serde::Deserialize;
use std::sync::Arc;

#[derive(Deserialize)]
struct UpdateNote {
    title: String,
}

struct AppState;

// URUTAN BENAR: Path, State (tidak menyentuh body) -> Json (menyentuh body, PALING TERAKHIR)
async fn update_note(
    Path(id): Path<u32>,
    State(_state): State<Arc<AppState>>,
    Json(payload): Json<UpdateNote>,
) -> String {
    format!("Catatan {} diupdate jadi '{}'", id, payload.title)
}

// URUTAN SALAH (tidak akan kompilasi):
// async fn broken(Json(payload): Json<UpdateNote>, Path(id): Path<u32>) -> String { ... }

#[tokio::main]
async fn main() {
    let state = Arc::new(AppState);
    let app = Router::new()
        .route("/notes/{id}", put(update_note))
        .with_state(state);

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

Praktikum

Perbaiki urutan parameter pada handler di bawah supaya bisa dikompilasi — `Json<T>` harus di posisi paling akhir.

Editor Latihan

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

Tips

Kalau butuh membaca body DAN beberapa extractor lain yang sama-sama "istimewa" (misalnya `Request` mentah), letakkan extractor paling generik/mentah di posisi paling akhir juga. Aturan sederhananya: makin spesifik/aman extractor-nya (Path, Query, State, header), makin awal boleh diletakkan; makin dia "melahap" seluruh request, makin ke belakang.