Created
July 18, 2018 11:11
-
-
Save aleics/814aa082afd5066eb3cd86adf22e652f to your computer and use it in GitHub Desktop.
Diesel connection with the Rocket Framework
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use r2d2::{Pool, PooledConnection, Error}; | |
use r2d2_diesel::ConnectionManager; | |
use diesel::PgConnection; | |
use rocket::http::Status; | |
use rocket::{Request, State, Outcome}; | |
use rocket::request::{self, FromRequest}; | |
/// DatabaseHandler handles a single connection to the database | |
pub struct DatabaseHandler { | |
conn: PooledConnection<ConnectionManager<PgConnection>> | |
} | |
impl DatabaseHandler { | |
// Get a connection from the pooled connection | |
pub fn conn(&self) -> &PgConnection { | |
&*self.conn | |
} | |
} | |
/// Implementation of the `FromRequest` rocket trait for the DatabaseHandler struct. | |
/// This will allow us to retrieve a connection of the database dynamically for a given request. | |
impl<'a, 'r> FromRequest<'a, 'r> for DatabaseHandler { | |
type Error = (); | |
fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | |
let pool = request.guard::<State<Database>>()?; | |
match pool.handler() { | |
Ok(handler) => Outcome::Success(handler), | |
Err(_) => Outcome::Failure((Status::ServiceUnavailable, ())) | |
} | |
} | |
} | |
// Database manages the postgres database pool to retrieve and read connections | |
pub struct Database { | |
pool: Pool<ConnectionManager<PgConnection>>, | |
} | |
impl Database { | |
/// Initialization of the database pool | |
pub fn init(db_url: String) -> Database { | |
let manager = ConnectionManager::<PgConnection>::new(db_url); | |
Database { | |
pool: Pool::builder().build(manager).expect("unable to generate initial database pool") | |
} | |
} | |
/// Get a database handler for a given connection | |
pub fn handler(&self) -> Result<DatabaseHandler, Error> { | |
self.pool.get() | |
.map(|conn| DatabaseHandler { conn }) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(plugin)] | |
#![plugin(rocket_codegen)] | |
extern crate rocket; | |
extern crate r2d2; | |
extern crate r2d2_diesel; | |
#[macro_use] extern crate diesel; | |
extern crate serde; | |
extern crate serde_json; | |
#[macro_use] extern crate serde_derive; | |
mod db; | |
mod models; | |
mod schema; | |
use rocket::Rocket; | |
use db::{DatabaseHandler, Database}; | |
use models::User; | |
use serde::Serialize; | |
// Serialize any type into a JSON string | |
fn serialize<T: ?Sized>(val: &T) -> String where T: Serialize { | |
serde_json::to_string(val) | |
.unwrap_or(String::new()) | |
} | |
#[post("/graphql", format = "application/json")] | |
fn graphql_handler(handler: DatabaseHandler) -> String { | |
use schema::users::dsl::*; | |
use diesel::prelude::*; | |
let result: Vec<User> = users | |
.select((passport, name, age)) | |
.load::<User>(handler.conn()) | |
.unwrap(); | |
serialize(&result) | |
} | |
fn rocket(database: Database) -> Rocket { | |
rocket::ignite() | |
.manage(database) | |
.mount("/api", routes![graphql_handler]) | |
} | |
fn main() { | |
rocket(Database::init("postgres://postgres@172.11.0.3".to_string())) | |
.launch(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive(Debug, Queryable, Serialize)] | |
pub struct User { | |
passport: String, | |
name: String, | |
age: i32 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment