Guides
Turso + Axum
Set up Turso in your Axum project in minutes
Prerequisites
Before you start, make sure you:
- Install the Turso CLI
- Sign up or login to Turso
- Have an Axum app — learn more
1
Retrieve database credentials
You will need an existing database to continue. If you don’t have one, create one.
Get the database URL:
turso db show --url <database-name>
Get the database authentication token:
turso db tokens create <database-name>
Assign credentials to the environment variables inside .env
.
TURSO_DATABASE_URL=
TURSO_AUTH_TOKEN=
You will want to store these as environment variables.
2
Add the libsql crate to the project
cargo add libsql
Optionally, you can add a package such as dotenvy
to help you work with .env
files:
cargo add dotenvy
3
Execute 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
Use in an Axum handler
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();
}
This example creates a shared Database
instance in the application state, which is then used in the handler to execute queries.