# Database integration ## Diesel At the moment of 1.0 release Diesel does not support asynchronous operations. But it possible to use `actix` synchronous actor system as a db interface api. Technically sync actors are worker style actors, multiple of them can be run in parallel and process messages from same queue (sync actors work in mpmc mode). Let's create simple db api that can insert new user row into sqlite table. We have to define sync actor and connection that this actor will use. Same approach could used for other databases. ```rust,ignore use actix::prelude::*;* struct DbExecutor(SqliteConnection); impl Actor for DbExecutor { type Context = SyncContext; } ``` This is definition of our actor. Now we need to define *create user* message and response. ```rust,ignore #[derive(Message)] #[rtype(User, Error)] struct CreateUser { name: String, } ``` We can send `CreateUser` message to `DbExecutor` actor, and as result we get `User` model. Now we need to define actual handler implementation for this message. ```rust,ignore impl Handler for DbExecutor { fn handle(&mut self, msg: CreateUser, _: &mut Self::Context) -> Response { use self::schema::users::dsl::*; // Create insertion model let uuid = format!("{}", uuid::Uuid::new_v4()); let new_user = models::NewUser { id: &uuid, name: &msg.name, }; // normal diesl operations diesel::insert_into(users) .values(&new_user) .execute(&self.0) .expect("Error inserting person"); let mut items = users .filter(id.eq(&uuid)) .load::(&self.0) .expect("Error loading person"); Self::reply(items.pop().unwrap()) } } ``` That is it. Now we can use *DbExecutor* actor from any http handler or middleware. All we need is to start *DbExecutor* actors and store address in a state where http handler can access it. ```rust,ignore /// This is state where we will store *DbExecutor* address. struct State { db: SyncAddress, } fn main() { let sys = actix::System::new("diesel-example"); // Start 3 parallele db executors let addr = SyncArbiter::start(3, || { DbExecutor(SqliteConnection::establish("test.db").unwrap()) }); // Start http server HttpServer::new(move || { Application::with_state(State{db: addr.clone()}) .resource("/{name}", |r| r.method(Method::GET).a(index))}) .bind("127.0.0.1:8080").unwrap() .start().unwrap(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run(); } ``` And finally we can use address in a requst handler. We get message response asynchronously, so handler needs to return future object, also `Route::a()` needs to be used for async handler registration. ```rust,ignore /// Async handler fn index(req: HttpRequest) -> Box> { let name = &req.match_info()["name"]; // Send message to `DbExecutor` actor 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() } ``` Full example is available in [examples directory](https://github.com/actix/actix-web/tree/master/examples/diesel/). More information on sync actors could be found in [actix documentation](https://docs.rs/actix/0.3.3/actix/sync/index.html).