1
0
mirror of https://github.com/actix/examples synced 2025-06-28 18:00:37 +02:00

upgrade to 2.0 alpha.3

This commit is contained in:
Nikolay Kim
2019-12-07 23:59:24 +06:00
parent e7f7175b7b
commit 3127352797
100 changed files with 1075 additions and 1107 deletions

View File

@ -1,14 +1,16 @@
[package]
name = "actix-graphql-demo"
version = "0.1.0"
version = "2.0.0"
authors = ["Dwi Sulfahnur <hello@dwisulfahnur.com>"]
edition = "2018"
workspace = ".."
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
actix-web = "1.0"
futures = "0.1"
actix-web = "2.0.0-alpha.3"
actix-rt = "1.0.0-alpha.3"
futures = "0.3.1"
juniper = "0.13"

View File

@ -1,44 +1,42 @@
use std::sync::Arc;
use actix_web::{Error, HttpResponse, web};
use futures::Future;
use actix_web::{web, Error, HttpResponse};
use juniper::http::graphiql::graphiql_source;
use juniper::http::GraphQLRequest;
use crate::db::Pool;
use crate::schemas::root::{Context, create_schema, Schema};
use crate::schemas::root::{create_schema, Context, Schema};
pub fn graphql(
pub async fn graphql(
pool: web::Data<Pool>,
schema: web::Data<Arc<Schema>>,
data: web::Json<GraphQLRequest>,
) -> impl Future<Item=HttpResponse, Error=Error> {
) -> Result<HttpResponse, Error> {
let ctx = Context {
dbpool: pool.get_ref().to_owned(),
};
web::block(move || {
let res = web::block(move || {
let res = data.execute(&schema, &ctx);
Ok::<_, serde_json::error::Error>(serde_json::to_string(&res)?)
})
.map_err(Error::from)
.and_then(|res| {
Ok(HttpResponse::Ok()
.content_type("application/json")
.body(res))
})
.await
.map_err(Error::from)?;
Ok(HttpResponse::Ok()
.content_type("application/json")
.body(res))
}
pub fn graphql_playground() -> HttpResponse {
pub async fn graphql_playground() -> HttpResponse {
HttpResponse::Ok()
.content_type("text/html; charset=utf-8")
.body(graphiql_source("/graphql"))
}
pub fn register(config: &mut web::ServiceConfig) {
let schema = std::sync::Arc::new(create_schema());
config
.data(schema)
.route("/graphql", web::post().to_async(graphql))
.route("/graphql", web::post().to(graphql))
.route("/graphiql", web::get().to(graphql_playground));
}
}

View File

@ -4,16 +4,17 @@ extern crate r2d2;
extern crate r2d2_mysql;
extern crate serde_json;
use actix_web::{App, HttpServer, middleware, web};
use actix_web::{middleware, web, App, HttpServer};
use crate::db::get_db_pool;
use crate::handlers::{register};
use crate::handlers::register;
mod db;
mod handlers;
mod schemas;
mod db;
fn main() -> std::io::Result<()> {
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
dotenv::dotenv().ok();
std::env::set_var("RUST_LOG", "actix_web=info,info");
env_logger::init();
@ -24,8 +25,9 @@ fn main() -> std::io::Result<()> {
.data(pool.clone())
.wrap(middleware::Logger::default())
.configure(register)
.default_service(web::to(|| "404"))
.default_service(web::to(|| async { "404" }))
})
.bind("127.0.0.1:8080")?
.run()
}
.bind("127.0.0.1:8080")?
.start()
.await
}

View File

@ -1,3 +1,3 @@
pub mod product;
pub mod root;
pub mod user;
pub mod product;

View File

@ -1,5 +1,5 @@
use juniper;
use mysql::{Error as DBError, from_row, params, Row};
use mysql::{from_row, params, Error as DBError, Row};
use crate::schemas::root::Context;
use crate::schemas::user::User;
@ -36,7 +36,7 @@ impl Product {
);
if let Err(err) = user {
None
}else{
} else {
let (id, name, email) = from_row(user.unwrap().unwrap());
Some(User { id, name, email })
}
@ -49,4 +49,4 @@ pub struct ProductInput {
pub user_id: String,
pub name: String,
pub price: f64,
}
}

View File

@ -1,6 +1,6 @@
use juniper::{FieldError, FieldResult, RootNode};
use juniper;
use mysql::{Error as DBError, from_row, params, Row};
use juniper::{FieldError, FieldResult, RootNode};
use mysql::{from_row, params, Error as DBError, Row};
use crate::db::Pool;
@ -8,7 +8,7 @@ use super::product::{Product, ProductInput};
use super::user::{User, UserInput};
pub struct Context {
pub dbpool: Pool
pub dbpool: Pool,
}
impl juniper::Context for Context {}
@ -20,13 +20,18 @@ impl QueryRoot {
#[graphql(description = "List of all users")]
fn users(context: &Context) -> FieldResult<Vec<User>> {
let mut conn = context.dbpool.get().unwrap();
let users = conn.prep_exec("select * from user", ())
let users = conn
.prep_exec("select * from user", ())
.map(|result| {
result.map(|x| x.unwrap()).map(|mut row| {
let (id, name, email) = from_row(row);
User { id, name, email }
}).collect()
}).unwrap();
result
.map(|x| x.unwrap())
.map(|mut row| {
let (id, name, email) = from_row(row);
User { id, name, email }
})
.collect()
})
.unwrap();
Ok(users)
}
@ -34,10 +39,8 @@ impl QueryRoot {
fn user(context: &Context, id: String) -> FieldResult<User> {
let mut conn = context.dbpool.get().unwrap();
let user: Result<Option<Row>, DBError> = conn.first_exec(
"SELECT * FROM user WHERE id=:id",
params! {"id" => id},
);
let user: Result<Option<Row>, DBError> =
conn.first_exec("SELECT * FROM user WHERE id=:id", params! {"id" => id});
if let Err(err) = user {
return Err(FieldError::new(
@ -53,23 +56,31 @@ impl QueryRoot {
#[graphql(description = "List of all users")]
fn products(context: &Context) -> FieldResult<Vec<Product>> {
let mut conn = context.dbpool.get().unwrap();
let products = conn.prep_exec("select * from product", ())
let products = conn
.prep_exec("select * from product", ())
.map(|result| {
result.map(|x| x.unwrap()).map(|mut row| {
let (id, user_id, name, price) = from_row(row);
Product { id, user_id, name, price }
}).collect()
}).unwrap();
result
.map(|x| x.unwrap())
.map(|mut row| {
let (id, user_id, name, price) = from_row(row);
Product {
id,
user_id,
name,
price,
}
})
.collect()
})
.unwrap();
Ok(products)
}
#[graphql(description = "Get Single user reference by user ID")]
fn product(context: &Context, id: String) -> FieldResult<Product> {
let mut conn = context.dbpool.get().unwrap();
let product: Result<Option<Row>, DBError> = conn.first_exec(
"SELECT * FROM user WHERE id=:id",
params! {"id" => id},
);
let product: Result<Option<Row>, DBError> =
conn.first_exec("SELECT * FROM user WHERE id=:id", params! {"id" => id});
if let Err(err) = product {
return Err(FieldError::new(
"Product Not Found",
@ -78,11 +89,15 @@ impl QueryRoot {
}
let (id, user_id, name, price) = from_row(product.unwrap().unwrap());
Ok(Product { id, user_id, name, price })
Ok(Product {
id,
user_id,
name,
price,
})
}
}
pub struct MutationRoot;
#[juniper::object(Context = Context)]
@ -101,17 +116,15 @@ impl MutationRoot {
);
match insert {
Ok(opt_row) => {
Ok(User {
id: new_id,
name: user.name,
email: user.email,
})
}
Ok(opt_row) => Ok(User {
id: new_id,
name: user.name,
email: user.email,
}),
Err(err) => {
let msg = match err {
DBError::MySqlError(err) => err.message,
_ => "internal error".to_owned()
_ => "internal error".to_owned(),
};
Err(FieldError::new(
"Failed to create new user",
@ -136,18 +149,16 @@ impl MutationRoot {
);
match insert {
Ok(opt_row) => {
Ok(Product {
id: new_id,
user_id: product.user_id,
name: product.name,
price: product.price,
})
}
Ok(opt_row) => Ok(Product {
id: new_id,
user_id: product.user_id,
name: product.name,
price: product.price,
}),
Err(err) => {
let msg = match err {
DBError::MySqlError(err) => err.message,
_ => "internal error".to_owned()
_ => "internal error".to_owned(),
};
Err(FieldError::new(
"Failed to create new product",

View File

@ -19,27 +19,42 @@ pub struct UserInput {
pub email: String,
}
#[juniper::object(Context = Context)]
impl User {
fn id(&self) -> &str { &self.id }
fn id(&self) -> &str {
&self.id
}
fn name(&self) -> &str {
&self.name
}
fn email(&self) -> &str { &self.email }
fn email(&self) -> &str {
&self.email
}
fn products(&self, context: &Context) -> Vec<Product> {
let mut conn = context.dbpool.get().unwrap();
let products = conn.prep_exec(
"select * from product where user_id=:user_id", params! {
"user_id" => &self.id
})
let products = conn
.prep_exec(
"select * from product where user_id=:user_id",
params! {
"user_id" => &self.id
},
)
.map(|result| {
result.map(|x| x.unwrap()).map(|mut row| {
let (id, user_id, name, price) = from_row(row);
Product { id, user_id, name, price }
}).collect()
}).unwrap();
result
.map(|x| x.unwrap())
.map(|mut row| {
let (id, user_id, name, price) = from_row(row);
Product {
id,
user_id,
name,
price,
}
})
.collect()
})
.unwrap();
products
}
}