Integrasi Database dengan Sqlx
Penjelasan
Pola paling umum menghubungkan Axum ke database adalah lewat crate `sqlx` — driver database async yang cocok dengan runtime Tokio. Alih-alih membuka koneksi baru setiap request (mahal dan lambat), kamu membuat satu connection pool (`sqlx::PgPool` untuk PostgreSQL, `sqlx::MySqlPool` untuk MySQL) sekali saat aplikasi start, lalu menyimpannya di dalam `AppState` yang sudah kamu pelajari sebelumnya. Setiap handler yang butuh akses database cukup menerima `State<AppState>`, lalu mengambil pool dari dalamnya untuk menjalankan query. Sqlx pool sendiri sudah aman diakses secara bersamaan (thread-safe), jadi biasanya cukup dibungkus `Arc` saja seperti state pada umumnya, tanpa perlu `Mutex` tambahan. URL koneksi database biasanya diambil dari environment variable, misalnya `$DATABASE_URL`, supaya kredensial tidak ditulis langsung di source code. Contoh di bawah menunjukkan pola dasarnya secara singkat — detail query CRUD lengkap ada di luar cakupan topik ini.
Contoh Konsep
// cargo add sqlx --features runtime-tokio,postgres
use axum::{extract::State, routing::get, Router};
use sqlx::PgPool;
use std::sync::Arc;
struct AppState {
db: PgPool,
}
async fn list_notes(State(state): State<Arc<AppState>>) -> String {
let count: (i64,) = sqlx::query_as("SELECT COUNT(*) FROM notes")
.fetch_one(&state.db)
.await
.unwrap_or((0,));
format!("Jumlah catatan: {}", count.0)
}
#[tokio::main]
async fn main() {
// Ambil URL koneksi dari environment variable $DATABASE_URL
let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL harus di-set");
let pool = PgPool::connect(&database_url).await.unwrap();
let state = Arc::new(AppState { db: pool });
let app = Router::new()
.route("/notes", get(list_notes))
.with_state(state);
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
Praktikum
Lengkapi `AppState` supaya menyimpan `PgPool`, lalu buat handler `health` yang mengembalikan "database terhubung" tanpa perlu query apa pun (cukup buktikan state bisa diakses).
Ketik/edit bebas di sini untuk latihan — kode ini tidak dijalankan.
Tips
Simpan `$DATABASE_URL` di file `.env` (dan tambahkan `.env` ke `.gitignore`), lalu muat dengan crate `dotenvy` di awal `main` sebelum `std::env::var(...)` dipanggil — supaya kamu tidak perlu export environment variable manual tiap kali menjalankan `cargo run` saat development.