Query Extractor
Penjelasan
Query string adalah bagian URL setelah tanda tanya, misalnya `?page=2&limit=10`. Axum menyediakan extractor `Query<T>` untuk mem-parsing query string menjadi struct Rust secara otomatis, memakai Serde di baliknya. Berbeda dengan `Path<T>` yang segmen-segmennya wajib ada, field pada struct `Query<T>` biasanya opsional (dibungkus `Option<T>`) karena query string memang sering tidak lengkap — user bisa saja mengakses `/search` tanpa parameter apa pun. Kalau field wajib tapi tidak dikirim, Axum akan mengembalikan 400. Untuk memberi nilai default ketika parameter tidak dikirim, kombinasikan `Option<T>` dengan `.unwrap_or(...)` di dalam handler, atau pakai atribut `#[serde(default)]` pada field struct.
Contoh Konsep
use axum::{extract::Query, routing::get, Router};
use serde::Deserialize;
#[derive(Deserialize)]
struct Pagination {
page: Option<u32>,
limit: Option<u32>,
}
async fn list_notes(Query(pagination): Query<Pagination>) -> String {
let page = pagination.page.unwrap_or(1);
let limit = pagination.limit.unwrap_or(10);
format!("Menampilkan halaman {} dengan limit {}", page, limit)
}
#[tokio::main]
async fn main() {
let app = Router::new().route("/notes", get(list_notes));
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
// Akses: /notes?page=2&limit=5
Praktikum
Buat struct `SearchParams` dengan field `keyword: Option<String>`, lalu buat handler `search` yang mengembalikan pesan berbeda tergantung ada tidaknya keyword.
Ketik/edit bebas di sini untuk latihan — kode ini tidak dijalankan.
Tips
Kalau `Query<T>` gagal parsing (misalnya user mengirim `limit=abc` padahal field-nya `u32`), Axum mengembalikan 400 secara otomatis. Kalau kamu ingin pesan error yang lebih ramah, gunakan `Query<T>` versi `Result` dengan `extract::rejection::QueryRejection` — tapi untuk kebanyakan kasus, perilaku default sudah cukup.