Databaseintegrasjon
Vedvare data
Databaseintegrasjon er en gratis leksjon i Lær Rust-programmering på CoddyKit. Dette er leksjon 3 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Lær Rust-programmering, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Lær Rust-programmering inneholder totalt 4 leksjoner.
Persistens av data
Så langt har API-et vårt lagret data i minnet, og dataene forsvinner ved omstart. Ekte tjenester trenger en database. I denne leksjonen kobler vi et Axum-API til PostgreSQL ved hjelp av sqlx, et asynkront SQL-verktøysett for Rust med kompileringstidskontroll.
De skal lære om tilkoblingspooler, spørringer, tilordning av rader til strukturer og bruk av poolen som delt tilstand.
Legge til sqlx
Legg til sqlx med funksjonene De trenger: et kjøremiljø, TLS og en databasedriver. Nedenfor ser De et Postgres-oppsett som bruker Tokio.
// Cargo.toml
// [dependencies]
// sqlx = { version = "0.7", features = [
// "runtime-tokio", "tls-rustls", "postgres", "macros"
// ] }Tilkoblingspoolen
Det er tregt å åpne en ny tilkobling for hver forespørsel. En tilkoblingspool holder et sett med gjenbrukbare tilkoblinger. PgPoolOptions bygger en pool fra en database-URL. Poolen er billig å klone (den bruker referansetelling internt), noe som gjør den velegnet som delt tilstand.
use sqlx::postgres::PgPoolOptions;
async fn make_pool(url: &str) -> sqlx::PgPool {
PgPoolOptions::new()
.max_connections(5)
.connect(url)
.await
.expect("failed to connect")
}Poolen som applikasjonstilstand
Send poolen til Axum med .with_state(pool). Behandlerne tar deretter imot State(pool): State<PgPool>. Siden poolen kan klones billig, deler hver forespørsel de samme underliggende tilkoblingene.
use axum::{routing::get, Router};
use sqlx::PgPool;
fn build(pool: PgPool) -> Router {
Router::new()
.route("/todos", get(list_todos))
.with_state(pool)
}Kjøre en spørring
Funksjonen sqlx::query kjører rå SQL. Bind parametere med .bind(value) for å unngå SQL-injeksjon; Postgres bruker plassholdere som $1 og $2. Bruk .execute(&pool) for skriveoperasjoner som ikke returnerer rader.
use sqlx::PgPool;
async fn insert_todo(pool: &PgPool, title: &str) -> Result<(), sqlx::Error> {
sqlx::query("INSERT INTO todos (title, done) VALUES ($1, $2)")
.bind(title)
.bind(false)
.execute(pool)
.await?;
Ok(())
}Tilordne rader til strukturer
Deriver sqlx::FromRow på modellen Deres, slik at spørringsresultater kan tilordnes direkte til den. Bruk query_as::<_, Todo> sammen med fetch_all for å få en Vec<Todo>, eller fetch_one for én enkelt rad.
use sqlx::{PgPool, FromRow};
#[derive(FromRow, serde::Serialize)]
struct Todo { id: i32, title: String, done: bool }
async fn all_todos(pool: &PgPool) -> Result<Vec<Todo>, sqlx::Error> {
let rows = sqlx::query_as::<_, Todo>("SELECT id, title, done FROM todos")
.fetch_all(pool)
.await?;
Ok(rows)
}En behandler som leser databasen
Sett delene sammen: En behandler henter poolen fra tilstanden, kjører en spørring og returnerer JSON. Konverter databasefeil til statusen 500, slik at klienten får et ryddig svar i stedet for en panic.
use axum::{extract::State, Json, http::StatusCode};
use sqlx::PgPool;
async fn list_todos(
State(pool): State<PgPool>,
) -> Result<Json<Vec<Todo>>, StatusCode> {
match all_todos(&pool).await {
Ok(todos) => Ok(Json(todos)),
Err(_) => Err(StatusCode::INTERNAL_SERVER_ERROR),
}
}Returnere innsatte rader
Postgres kan returnere raden som nettopp ble satt inn, med RETURNING. Kombiner dette med query_as og fetch_one for å hente den nye posten, inkludert den genererte ID-en, i én enkelt rundtur.
use sqlx::PgPool;
async fn create(pool: &PgPool, title: &str) -> Result<Todo, sqlx::Error> {
let todo = sqlx::query_as::<_, Todo>(
"INSERT INTO todos (title, done) VALUES ($1, false) \
RETURNING id, title, done")
.bind(title)
.fetch_one(pool)
.await?;
Ok(todo)
}Migreringer
Skjemaet må finnes før spørringene kan kjøres. sqlx støtter migreringer: SQL-filer i en migrations/-mappe som brukes i rekkefølge. Kjør dem ved oppstart med sqlx::migrate!(), slik at en ny database settes opp automatisk.
use sqlx::PgPool;
async fn run_migrations(pool: &PgPool) {
sqlx::migrate!("./migrations")
.run(pool)
.await
.expect("migrations failed");
}
// migrations/0001_init.sql contains the CREATE TABLE statements.Transaksjoner
Når flere skriveoperasjoner må lykkes samlet, pakker De dem inn i en transaksjon. Start med pool.begin(), kjør spørringene mot transaksjonshåndtaket, og kall deretter commit. Hvis De forkaster det uten å bekrefte transaksjonen, ruller sqlx automatisk tilbake, slik at dataene forblir konsistente.
use sqlx::PgPool;
async fn transfer(pool: &PgPool) -> Result<(), sqlx::Error> {
let mut tx = pool.begin().await?;
sqlx::query("UPDATE accounts SET balance = balance - 10 WHERE id = 1")
.execute(&mut *tx).await?;
sqlx::query("UPDATE accounts SET balance = balance + 10 WHERE id = 2")
.execute(&mut *tx).await?;
tx.commit().await?;
Ok(())
}Konfigurasjon og hemmeligheter
Hardkod aldri databaselegitimasjon. Les DATABASE_URL fra miljøet, ofte lastet fra en .env-fil med craten dotenvy under utvikling. I produksjon injiserer plattformen den som en miljøvariabel.
use std::env;
async fn connect_from_env() -> sqlx::PgPool {
let url = env::var("DATABASE_URL")
.expect("DATABASE_URL must be set");
make_pool(&url).await
}Kort kontroll
Test forståelsen Deres av databaseintegrasjon.
Oppsummering
De har integrert en database:
- Bruk en
PgPool-tilkoblingspool og del den via.with_state. - Bruk
query/executefor skriving ogquery_asmedFromRowfor typesikre lesinger. - Bind alltid parametere for å forhindre SQL-injeksjon.
RETURNINGhenter innlagte rader, og transaksjoner grupperer skriving atomisk.- Kjør migreringer ved oppstart, og les
DATABASE_URLfra miljøet.
Lær deg Rust med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 39
- Leksjoner
- 144
Ofte stilte spørsmål
Er leksjonen «Databaseintegrasjon» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Lær Rust-programmering, inkludert «Databaseintegrasjon», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Lær Rust-programmering inneholder totalt 4 leksjoner.
Hva lærer jeg i «Databaseintegrasjon»?
Vedvare data Du øver på Lær Rust-programmering med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Lær Rust-programmering?
Ingen tidligere erfaring er nødvendig. Lær Rust-programmering på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.
Hvor lang tid tar leksjonen «Databaseintegrasjon»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Lær Rust-programmering-leksjonen?
Ja. Alle Lær Rust-programmering-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Prosjektoppsett
- Endepunkter og modeller
- Databaseintegrasjon
- Teste API-et