본문 바로가기
WIKI 기술 지식 베이스

Turso + Axum

원문 보기 위키 갱신

Axum 프로젝트에도 몇 분이면 Turso를 붙일 수 있어요. 이 가이드는 자격 증명 준비부터 libsql 크레이트 추가, 원격 데이터베이스 쿼리, 그리고 Axum 핸들러에서 데이터베이스를 공유하는 패턴까지 안내해요.

출처: 문서

본문

시작 전 준비물

시작하기 전에 다음을 확인해 주세요.

단계별 진행

1. 데이터베이스 자격 증명 가져오기

계속하려면 기존 데이터베이스가 필요해요. 없다면 먼저 데이터베이스를 만들어 주세요. 데이터베이스 URL과 인증 토큰을 확보한 뒤에는 환경 변수로 저장해 두는 편이 좋아요.

2. 프로젝트에 libsql 크레이트 추가하기

cargo add libsql

참고: 선택 사항으로, .env 파일을 다룰 때 도움이 되는 dotenvy 같은 패키지를 추가할 수도 있어요.

cargo add dotenvy

3. SQL 실행하기

use libsql::{Builder, Connection, Database, Result};

#[tokio::main]
async fn main() -> Result<()> {
    dotenv().ok();

    let db_url = std::env::var("TURSO_DATABASE_URL").expect("TURSO_DATABASE_URL must be set");
    let auth_token = std::env::var("TURSO_AUTH_TOKEN").expect("TURSO_AUTH_TOKEN must be set");

    let db = Builder::new_remote(db_url, auth_token)
        .build()
        .await?;

    let conn = db.connect()?;

    // Execute a query
    let mut rows = conn.query("SELECT * FROM users", ()).await?;

    while let Some(row) = rows.next().await? {
        let id: i64 = row.get(0)?;
        let name: String = row.get(1)?;
        println!("User: {} - {}", id, name);
    }

    Ok(())
}

4. Axum 핸들러에서 사용하기

use axum::{
    extract::State,
    routing::get,
    Json, Router,
};
use libsql::{Builder, Connection, Database};
use serde::Serialize;

#[derive(Clone)]
struct AppState {
    db: Database,
}

#[derive(Serialize)]
struct User {
    id: i64,
    name: String,
}

async fn get_users(State(state): State<AppState>) -> Json<Vec<User>> {
    let conn = state.db.connect().unwrap();
    let mut rows = conn.query("SELECT id, name FROM users", ()).await.unwrap();

    let mut users = Vec::new();
    while let Some(row) = rows.next().await.unwrap() {
        users.push(User {
            id: row.get(0).unwrap(),
            name: row.get(1).unwrap(),
        });
    }

    Json(users)
}

#[tokio::main]
async fn main() {
    let db_url = std::env::var("TURSO_DATABASE_URL").expect("TURSO_DATABASE_URL must be set");
    let auth_token = std::env::var("TURSO_AUTH_TOKEN").expect("TURSO_AUTH_TOKEN must be set");

    let db = Builder::new_remote(db_url, auth_token)
        .build()
        .await
        .unwrap();

    let app_state = AppState { db };

    let app = Router::new()
        .route("/users", get(get_users))
        .with_state(app_state);

    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

이 예제는 애플리케이션 상태에 공유 Database 인스턴스를 만들고, 핸들러에서 그 인스턴스로 쿼리를 실행해요.

더 알아보기 (Learn more)