Skip to content

Commit 3d30614

Browse files
authored
Merge pull request #2 from korir248/main
changes from main
2 parents 5fb1919 + c552ad0 commit 3d30614

File tree

10 files changed

+125
-18
lines changed

10 files changed

+125
-18
lines changed

examples/web_app_graphql/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ meilisearch-sdk = "0.24.3"
2323
serde = { version = "1.0.192", features = ["derive"] }
2424
serde_json = "1.0.108"
2525
thiserror = "1.0.51"
26+
validator = { version = "0.16.1", features = ["derive"] }
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
use async_graphql::SimpleObject;
22
pub mod users;
33

4-
use users::UsersQuery;
4+
use users::mutation::UsersMut;
5+
use users::query::UsersQuery;
56

67
#[derive(Default, SimpleObject)]
78
pub struct Query {
89
users: UsersQuery,
910
}
11+
12+
#[derive(Default, SimpleObject)]
13+
pub struct Mutation {
14+
users: UsersMut,
15+
}
Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,2 @@
1-
use async_graphql::MergedObject;
2-
pub mod get_users;
3-
pub mod search;
4-
5-
use get_users::GetUsers;
6-
use search::SearchUsers;
7-
8-
//Combines user queries into one struct
9-
#[derive(Default, MergedObject)]
10-
pub struct UsersQuery(pub GetUsers, pub SearchUsers);
1+
pub mod mutation;
2+
pub mod query;
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use async_graphql::{Context, InputObject, Object, Result};
2+
use diesel_async::RunQueryDsl;
3+
use validator::Validate;
4+
5+
use crate::{
6+
models::{NewUser, User},
7+
validate_input, GraphQlData,
8+
};
9+
10+
#[derive(Default)]
11+
pub struct AddUser;
12+
13+
#[derive(InputObject, Validate)]
14+
pub struct IAddUser {
15+
#[validate(length(min = 1))]
16+
pub first_name: String,
17+
#[validate(length(min = 1))]
18+
pub last_name: String,
19+
#[validate(email)]
20+
pub email: String,
21+
}
22+
23+
#[Object]
24+
impl AddUser {
25+
///Resolver for creating a new user and storing that data in the database
26+
///
27+
/// The mutation can be run as follows
28+
/// ```gpl
29+
/// mutation AddUser{
30+
/// users {
31+
/// signup(input: {firstName: "",lastName: "",email: ""}){
32+
/// id
33+
/// firstName
34+
/// lastName
35+
/// email
36+
/// }
37+
/// }
38+
/// }
39+
pub async fn signup(&self, ctx: &Context<'_>, input: IAddUser) -> Result<User> {
40+
validate_input(&input)?;
41+
42+
use crate::schema::users::dsl::users;
43+
44+
let GraphQlData { pool, .. } = ctx.data().map_err(|e| {
45+
log::error!("Failed to get app data: {:?}", e);
46+
e
47+
})?;
48+
49+
let mut connection = pool.get().await?;
50+
51+
let value = NewUser {
52+
first_name: input.first_name,
53+
last_name: input.last_name,
54+
email: input.email,
55+
};
56+
57+
let result = diesel::insert_into(users)
58+
.values(&value)
59+
.get_result::<User>(&mut connection)
60+
.await
61+
.map_err(|e| {
62+
log::error!("Could not create new user: {:#?}", e);
63+
e
64+
})?;
65+
66+
Ok(result)
67+
}
68+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
pub mod add_user;
2+
3+
use add_user::AddUser;
4+
use async_graphql::MergedObject;
5+
6+
//Combines user queries into one struct
7+
#[derive(Default, MergedObject)]
8+
pub struct UsersMut(pub AddUser);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
pub mod get_users;
2+
pub mod search;
3+
4+
use async_graphql::MergedObject;
5+
use get_users::GetUsers;
6+
use search::SearchUsers;
7+
8+
//Combines user queries into one struct
9+
#[derive(Default, MergedObject)]
10+
pub struct UsersQuery(pub GetUsers, pub SearchUsers);

examples/web_app_graphql/src/lib.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,22 @@ mod schema;
66

77
use actix_web::{web, HttpResponse, Result};
88
use app_env_vars::AppEnvVars;
9-
use async_graphql::{http::GraphiQLSource, EmptyMutation, EmptySubscription, Schema};
9+
use async_graphql::{
10+
http::GraphiQLSource, EmptySubscription, Error, Result as GraphqlResult, Schema,
11+
};
1012
use async_graphql_actix_web::{GraphQLRequest, GraphQLResponse};
1113
use diesel_async::{
1214
pooled_connection::{deadpool::Pool, AsyncDieselConnectionManager},
1315
AsyncPgConnection,
1416
};
1517
use errors::ApplicationError;
16-
use graphql_schema::Query;
18+
use graphql_schema::{Mutation, Query};
1719
use meilisearch_sdk::Client as SearchClient;
20+
use validator::Validate;
1821

19-
pub type ApplicationSchema = Schema<Query, EmptyMutation, EmptySubscription>;
22+
pub type ApplicationSchema = Schema<Query, Mutation, EmptySubscription>;
2023

21-
//Represents application data passed to graphql resolvers
24+
/// Represents application data passed to graphql resolvers
2225
pub struct GraphQlData {
2326
pub pool: Pool<AsyncPgConnection>,
2427
pub client: SearchClient,
@@ -36,7 +39,7 @@ pub async fn index(schema: web::Data<ApplicationSchema>, req: GraphQLRequest) ->
3639
schema.execute(req_inner).await.into()
3740
}
3841

39-
//We build the graphql schema and any data required to be passed to all resolvers
42+
/// We build the graphql schema and any data required to be passed to all resolvers
4043
pub fn build_schema(app_env_vars: &AppEnvVars) -> Result<ApplicationSchema, ApplicationError> {
4144
let client = SearchClient::new(
4245
&app_env_vars.meilisearch_host,
@@ -49,8 +52,19 @@ pub fn build_schema(app_env_vars: &AppEnvVars) -> Result<ApplicationSchema, Appl
4952
let schema_data = GraphQlData { pool, client };
5053

5154
Ok(
52-
Schema::build(Query::default(), EmptyMutation, EmptySubscription)
55+
Schema::build(Query::default(), Mutation::default(), EmptySubscription)
5356
.data(schema_data)
5457
.finish(),
5558
)
5659
}
60+
61+
/// Helper function for returning an error if inputs do not match the set conditions
62+
pub fn validate_input<T: Validate>(input: &T) -> GraphqlResult<()> {
63+
if let Err(e) = input.validate() {
64+
log::error!("Validation error: {}", e);
65+
let err = serde_json::to_string(&e).unwrap();
66+
let err = Error::from(err);
67+
return Err(err);
68+
}
69+
Ok(())
70+
}

examples/web_app_graphql/src/models.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use async_graphql::SimpleObject;
2-
use diesel::{Queryable, Selectable};
2+
use diesel::{prelude::Insertable, Queryable, Selectable};
33
use serde::{Deserialize, Serialize};
44

55
use crate::schema::users;
@@ -13,3 +13,11 @@ pub struct User {
1313
pub last_name: String,
1414
pub email: String,
1515
}
16+
17+
#[derive(Insertable, Debug)]
18+
#[diesel(table_name = users)]
19+
pub struct NewUser {
20+
pub first_name: String,
21+
pub last_name: String,
22+
pub email: String,
23+
}

0 commit comments

Comments
 (0)