Shared State dengan State<T>
Penjelasan
Kebanyakan aplikasi web butuh data yang dipakai bersama oleh banyak handler — koneksi database, konfigurasi, atau cache in-memory. Axum menyediakan extractor `State<T>` untuk kebutuhan ini. Alurnya: kamu membuat nilai state (misalnya `struct AppState`), lalu mendaftarkannya ke router lewat `.with_state(state)`. Setelah itu, handler mana pun bisa menerima state tersebut cukup dengan menambahkan parameter `State(state): State<AppState>`. Karena Rust punya aturan ownership yang ketat, dan state ini dipakai bersamaan oleh banyak task async, state biasanya dibungkus `Arc<T>` (Atomic Reference Counted) supaya bisa di-clone murah (hanya menambah reference count, bukan meng-copy datanya) dan aman diakses dari banyak thread sekaligus. Kalau field di dalam state perlu diubah (bukan cuma dibaca), tambahkan `Mutex` atau `RwLock` di dalamnya — tapi untuk kebanyakan kasus (misalnya pool koneksi database), state cukup dibungkus `Arc` saja karena pool sendiri sudah aman diakses concurrent.
Contoh Konsep
use axum::{extract::State, routing::get, Router};
use std::sync::Arc;
struct AppState {
app_name: String,
}
async fn show_name(State(state): State<Arc<AppState>>) -> String {
format!("Nama aplikasi: {}", state.app_name)
}
#[tokio::main]
async fn main() {
let shared_state = Arc::new(AppState {
app_name: "Catatan API".to_string(),
});
let app = Router::new()
.route("/", get(show_name))
.with_state(shared_state);
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
Praktikum
Buat `AppState` dengan field `version: String`, lalu handler `show_version` yang menampilkannya, dan daftarkan state ke router.
Ketik/edit bebas di sini untuk latihan — kode ini tidak dijalankan.
Tips
Kalau lupa memanggil `.with_state(...)` setelah handler memakai extractor `State<T>`, kompilasi akan gagal dengan pesan error yang cukup panjang soal trait `Handler` tidak terpenuhi. Ini normal — cukup pastikan `.with_state()` dipanggil PALING TERAKHIR setelah semua `.route()` didaftarkan.