Actix Web
Postgres Todo App
This example shows how to make a simple TODO app using Actix Web and a shared Shuttle Postgres DB.
use actix_web::middleware::Logger;
use actix_web::{
error, get, post,
web::{self, Json, ServiceConfig},
Result,
};
use serde::{Deserialize, Serialize};
use shuttle_actix_web::ShuttleActixWeb;
use shuttle_runtime::{CustomError};
use sqlx::{Executor, FromRow, PgPool};
#[get("/{id}")]
async fn retrieve(path: web::Path<i32>, state: web::Data<AppState>) -> Result<Json<Todo>> {
let todo = sqlx::query_as("SELECT * FROM todos WHERE id = $1")
.bind(*path)
.fetch_one(&state.pool)
.await
.map_err(|e| error::ErrorBadRequest(e.to_string()))?;
Ok(Json(todo))
}
#[post("")]
async fn add(todo: web::Json<TodoNew>, state: web::Data<AppState>) -> Result<Json<Todo>> {
let todo = sqlx::query_as("INSERT INTO todos(note) VALUES ($1) RETURNING id, note")
.bind(&todo.note)
.fetch_one(&state.pool)
.await
.map_err(|e| error::ErrorBadRequest(e.to_string()))?;
Ok(Json(todo))
}
#[derive(Clone)]
struct AppState {
pool: PgPool,
}
#[shuttle_runtime::main]
async fn actix_web(
#[shuttle_shared_db::Postgres] pool: PgPool,
) -> ShuttleActixWeb<impl FnOnce(&mut ServiceConfig) + Send + Clone + 'static> {
pool.execute(include_str!("../schema.sql"))
.await
.map_err(CustomError::new)?;
let state = web::Data::new(AppState { pool });
let config = move |cfg: &mut ServiceConfig| {
cfg.service(
web::scope("/todos")
.wrap(Logger::default())
.service(retrieve)
.service(add)
.app_data(state),
);
};
Ok(config.into())
}
#[derive(Deserialize)]
struct TodoNew {
pub note: String,
}
#[derive(Serialize, Deserialize, FromRow)]
struct Todo {
pub id: i32,
pub note: String,
}
Was this page helpful?