1
0
mirror of https://github.com/actix/examples synced 2025-06-29 10:14:58 +02:00

Rename graphql-demo to juniper-advanced

This commit is contained in:
Yuki Okushi
2020-05-19 14:23:28 +09:00
parent bc6f614f78
commit 3730fa8f55
13 changed files with 8 additions and 5 deletions

View File

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

View File

@ -0,0 +1,51 @@
use mysql::{from_row, params, Error as DBError, Row};
use crate::schemas::root::Context;
use crate::schemas::user::User;
/// Product
#[derive(Default, Debug)]
pub struct Product {
pub id: String,
pub user_id: String,
pub name: String,
pub price: f64,
}
#[juniper::object(Context = Context)]
impl Product {
fn id(&self) -> &str {
&self.id
}
fn user_id(&self) -> &str {
&self.user_id
}
fn name(&self) -> &str {
&self.name
}
fn price(&self) -> f64 {
self.price
}
fn user(&self, context: &Context) -> Option<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" => &self.user_id},
);
if let Err(err) = user {
None
} else {
let (id, name, email) = from_row(user.unwrap().unwrap());
Some(User { id, name, email })
}
}
}
#[derive(GraphQLInputObject)]
#[graphql(description = "Product Input")]
pub struct ProductInput {
pub user_id: String,
pub name: String,
pub price: f64,
}

View File

@ -0,0 +1,175 @@
use juniper::{FieldError, FieldResult, RootNode};
use mysql::{from_row, params, Error as DBError, Row};
use crate::db::Pool;
use super::product::{Product, ProductInput};
use super::user::{User, UserInput};
pub struct Context {
pub dbpool: Pool,
}
impl juniper::Context for Context {}
pub struct QueryRoot;
#[juniper::object(Context = Context)]
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", ())
.map(|result| {
result
.map(|x| x.unwrap())
.map(|mut row| {
let (id, name, email) = from_row(row);
User { id, name, email }
})
.collect()
})
.unwrap();
Ok(users)
}
#[graphql(description = "Get Single user reference by user ID")]
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});
if let Err(err) = user {
return Err(FieldError::new(
"User Not Found",
graphql_value!({ "not_found": "user not found" }),
));
}
let (id, name, email) = from_row(user.unwrap().unwrap());
Ok(User { id, name, email })
}
#[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", ())
.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();
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});
if let Err(err) = product {
return Err(FieldError::new(
"Product Not Found",
graphql_value!({ "not_found": "product not found" }),
));
}
let (id, user_id, name, price) = from_row(product.unwrap().unwrap());
Ok(Product {
id,
user_id,
name,
price,
})
}
}
pub struct MutationRoot;
#[juniper::object(Context = Context)]
impl MutationRoot {
fn create_user(context: &Context, user: UserInput) -> FieldResult<User> {
let mut conn = context.dbpool.get().unwrap();
let new_id = uuid::Uuid::new_v4().to_simple().to_string();
let insert: Result<Option<Row>, DBError> = conn.first_exec(
"INSERT INTO user(id, name, email) VALUES(:id, :name, :email)",
params! {
"id" => &new_id,
"name" => &user.name,
"email" => &user.email,
},
);
match insert {
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(),
};
Err(FieldError::new(
"Failed to create new user",
graphql_value!({ "internal_error": msg }),
))
}
}
}
fn create_product(context: &Context, product: ProductInput) -> FieldResult<Product> {
let mut conn = context.dbpool.get().unwrap();
let new_id = uuid::Uuid::new_v4().to_simple().to_string();
let insert: Result<Option<Row>, DBError> = conn.first_exec(
"INSERT INTO product(id, user_id, name, price) VALUES(:id, :user_id, :name, :price)",
params! {
"id" => &new_id,
"user_id" => &product.user_id,
"name" => &product.name,
"price" => &product.price.to_owned(),
},
);
match insert {
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(),
};
Err(FieldError::new(
"Failed to create new product",
graphql_value!({ "internal_error": msg }),
))
}
}
}
}
pub type Schema = RootNode<'static, QueryRoot, MutationRoot>;
pub fn create_schema() -> Schema {
Schema::new(QueryRoot, MutationRoot)
}

View File

@ -0,0 +1,58 @@
use mysql::{from_row, params};
use crate::schemas::product::Product;
use crate::schemas::root::Context;
/// User
#[derive(Default, Debug)]
pub struct User {
pub id: String,
pub name: String,
pub email: String,
}
#[derive(GraphQLInputObject)]
#[graphql(description = "User Input")]
pub struct UserInput {
pub name: String,
pub email: String,
}
#[juniper::object(Context = Context)]
impl User {
fn id(&self) -> &str {
&self.id
}
fn name(&self) -> &str {
&self.name
}
fn email(&self) -> &str {
&self.email
}
fn products(&self, context: &Context) -> Vec<Product> {
let mut conn = context.dbpool.get().unwrap();
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()
}
}