1
0
mirror of https://github.com/actix/examples synced 2025-01-23 14:24:35 +01:00

95 lines
2.8 KiB
Rust
Raw Normal View History

//! Actix web Diesel integration example
//!
//! Diesel does not support tokio, so we have to run it in separate threads using the web::block
//! function which offloads blocking code (like Diesel's) in order to not block the server's thread.
#[macro_use]
extern crate diesel;
use actix_web::{get, middleware, post, web, App, Error, HttpResponse, HttpServer};
use diesel::prelude::*;
2019-03-07 14:50:29 -08:00
use diesel::r2d2::{self, ConnectionManager};
use uuid::Uuid;
mod actions;
mod models;
mod schema;
type DbPool = r2d2::Pool<ConnectionManager<SqliteConnection>>;
/// Finds user by UID.
#[get("/user/{user_id}")]
async fn get_user(
pool: web::Data<DbPool>,
user_uid: web::Path<Uuid>,
2019-12-07 23:59:24 +06:00
) -> Result<HttpResponse, Error> {
let user_uid = user_uid.into_inner();
let conn = pool.get().expect("couldn't get db connection from pool");
2019-12-07 23:59:24 +06:00
// use web::block to offload blocking Diesel code without blocking server thread
let user = web::block(move || actions::find_user_by_uid(user_uid, &conn))
.await
.map_err(|e| {
eprintln!("{}", e);
HttpResponse::InternalServerError().finish()
})?;
if let Some(user) = user {
Ok(HttpResponse::Ok().json(user))
} else {
let res = HttpResponse::NotFound()
.body(format!("No user found with uid: {}", user_uid));
Ok(res)
2019-12-07 23:59:24 +06:00
}
}
/// Inserts new user with name defined in form.
#[post("/user")]
async fn add_user(
pool: web::Data<DbPool>,
form: web::Json<models::NewUser>,
2019-12-07 23:59:24 +06:00
) -> Result<HttpResponse, Error> {
let conn = pool.get().expect("couldn't get db connection from pool");
// use web::block to offload blocking Diesel code without blocking server thread
let user = web::block(move || actions::insert_new_user(&form.name, &conn))
2019-12-07 23:59:24 +06:00
.await
.map_err(|e| {
eprintln!("{}", e);
HttpResponse::InternalServerError().finish()
})?;
2019-12-07 23:59:24 +06:00
Ok(HttpResponse::Ok().json(user))
}
2020-09-12 16:49:45 +01:00
#[actix_web::main]
2019-12-07 23:59:24 +06:00
async fn main() -> std::io::Result<()> {
2020-05-20 19:34:41 +08:00
std::env::set_var("RUST_LOG", "actix_web=info");
env_logger::init();
dotenv::dotenv().ok();
// set up database connection pool
let connspec = std::env::var("DATABASE_URL").expect("DATABASE_URL");
let manager = ConnectionManager::<SqliteConnection>::new(connspec);
2018-05-08 11:08:43 -07:00
let pool = r2d2::Pool::builder()
.build(manager)
.expect("Failed to create pool.");
let bind = "127.0.0.1:8080";
println!("Starting server at: {}", &bind);
// Start HTTP server
2019-03-07 14:50:29 -08:00
HttpServer::new(move || {
App::new()
// set up DB pool to be used with web::Data<Pool> extractor
2019-03-26 04:29:00 +01:00
.data(pool.clone())
.wrap(middleware::Logger::default())
.service(get_user)
.service(add_user)
2019-03-07 14:50:29 -08:00
})
.bind(&bind)?
2019-12-25 20:48:33 +04:00
.run()
2019-12-07 23:59:24 +06:00
.await
}