//! Actix web diesel example //! //! Diesel does not support tokio, so we have to run it in separate threads. //! Actix supports sync actors by default, so we going to create sync actor that will //! use diesel. Technically sync actors are worker style actors, multiple of them //! can run in parallel and process messages from same queue. extern crate serde; extern crate serde_json; #[macro_use] extern crate serde_derive; #[macro_use] extern crate diesel; extern crate uuid; extern crate futures; extern crate actix; extern crate actix_web; extern crate env_logger; use actix::*; use actix_web::*; use diesel::prelude::*; use futures::future::Future; mod db; mod models; mod schema; use db::{CreateUser, DbExecutor}; /// State with DbExecutor address struct State { db: SyncAddress, } /// Async request handler fn index(req: HttpRequest) -> Box> { let name = &req.match_info()["name"]; req.state().db.call_fut(CreateUser{name: name.to_owned()}) .from_err() .and_then(|res| { match res { Ok(user) => Ok(httpcodes::HTTPOk.build().json(user)?), Err(_) => Ok(httpcodes::HTTPInternalServerError.into()) } }) .responder() } fn main() { ::std::env::set_var("RUST_LOG", "actix_web=info"); let _ = env_logger::init(); let sys = actix::System::new("diesel-example"); // Start db executor actors let addr = SyncArbiter::start(3, || { DbExecutor(SqliteConnection::establish("test.db").unwrap()) }); // Start http server let _addr = HttpServer::new(move || { Application::with_state(State{db: addr.clone()}) // enable logger .middleware(middleware::Logger::default()) .resource("/{name}", |r| r.method(Method::GET).a(index))}) .bind("127.0.0.1:8080").unwrap() .start(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run(); }