Study
Axum

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).

Editor Latihan

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.