Rapina Rapina /Tutorial
Read the docs

Database Basics

Rapina provides the Db extractor for database access. It gives you a connection from the pool, ready to query.

Define your table schema with the schema! macro:

schema! {
    table todos {
        id: u64,
        title: String,
        done: bool,
    }
}

Then use the Db extractor in your handler:

async fn handler(db: Db) -> Json<Vec<T>> {
    let todos = db.query("SELECT id, title, done FROM todos")
        .fetch_all()
        .await?;
    Json(todos)
}

The connection is automatically returned to the pool when the handler completes.

Assignment

  1. Add db: Db as a handler parameter
  2. Define a todos table schema using the schema! macro with fields id, title, and done
  3. Use db.query(...) to fetch todos and return them

This is the final chapter — you've learned the core concepts of Rapina. From here, explore the full documentation to go deeper.

Show answer
use rapina::prelude::*;

schema! {
    table todos {
        id: u64,
        title: String,
        done: bool,
    }
}

#[derive(Serialize, JsonSchema)]
struct TodoResponse {
    id: u64,
    title: String,
    done: bool,
}

#[public]
#[get("/todos")]
async fn list_todos(db: Db) -> Json<Vec<TodoResponse>> {
    let todos = db.query("SELECT id, title, done FROM todos")
        .fetch_all()
        .await
        .unwrap();
    Json(todos)
}
Tests
All tests passing — nice work!
main.rs
Response Preview
Complete the tests to see the response preview.
Previous 6 / 6