Skip to content

Commit fde462a

Browse files
committed
Graphql schema and error handling
1 parent 8783cc3 commit fde462a

File tree

5 files changed

+128
-0
lines changed

5 files changed

+128
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use diesel::ConnectionError;
2+
use diesel_async::pooled_connection::deadpool::{BuildError, PoolError};
3+
use diesel_migrations::MigrationError;
4+
use serde_json::Error as SerdeError;
5+
use thiserror::Error;
6+
7+
#[derive(Debug, Error)]
8+
pub enum ApplicationError {
9+
#[error("Missing environment variable")]
10+
Envy(#[from] envy::Error),
11+
#[error("Input/Output error")]
12+
Io(#[from] std::io::Error),
13+
#[error("Database error")]
14+
Diesel(#[from] diesel::result::Error),
15+
#[error("Deadpool build error")]
16+
DeadpoolBuild(#[from] BuildError),
17+
#[error("Migration error")]
18+
Migration(#[from] MigrationError),
19+
#[error("Connection error")]
20+
DieselConnection(#[from] ConnectionError),
21+
#[error("Pool Error")]
22+
Pool(#[from] PoolError),
23+
#[error("Serde json error")]
24+
SerDe(#[from] SerdeError),
25+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use async_graphql::SimpleObject;
2+
pub mod users;
3+
4+
use users::UsersQuery;
5+
6+
#[derive(Default, SimpleObject)]
7+
pub struct Query {
8+
users: UsersQuery,
9+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use async_graphql::{Context, Object, Result};
2+
use diesel_async::RunQueryDsl;
3+
4+
use crate::{models::User, GraphQlData};
5+
6+
#[derive(Default)]
7+
pub struct GetUsers;
8+
9+
#[Object]
10+
impl GetUsers {
11+
pub async fn get_users(&self, ctx: &Context<'_>) -> Result<Vec<User>> {
12+
use crate::schema::users::dsl::users;
13+
14+
let GraphQlData { pool, .. } = ctx.data().map_err(|e| {
15+
log::error!("Failed to get app data: {:?}", e);
16+
e
17+
})?;
18+
19+
let mut connection = pool.get().await?;
20+
21+
let list_users = users.load::<User>(&mut connection).await?;
22+
23+
Ok(list_users)
24+
}
25+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
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+
#[derive(Default, MergedObject)]
9+
pub struct UsersQuery(pub GetUsers, pub SearchUsers);
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use async_graphql::{Context, Object, Result};
2+
use diesel_async::RunQueryDsl;
3+
use meilisearch_sdk::search::{SearchQuery, SearchResults};
4+
5+
use crate::{models::User, GraphQlData};
6+
7+
#[derive(Default)]
8+
pub struct SearchUsers;
9+
10+
#[Object]
11+
impl SearchUsers {
12+
async fn search(&self, ctx: &Context<'_>, query_string: String) -> Result<Vec<User>> {
13+
use crate::schema::users::dsl::users;
14+
15+
let app_data = ctx.data::<GraphQlData>().map_err(|e| {
16+
log::error!("Failed to get app data: {:?}", e);
17+
e
18+
})?;
19+
20+
let mut connection = app_data.pool.get().await?;
21+
22+
let list_users = users.load::<User>(&mut connection).await?;
23+
24+
match app_data.client.get_index("users").await {
25+
Ok(index) => {
26+
index.add_documents(&list_users, Some("id")).await?;
27+
}
28+
Err(_) => {
29+
let task = app_data.client.create_index("users", Some("id")).await?;
30+
let task = task
31+
.wait_for_completion(&app_data.client, None, None)
32+
.await?;
33+
let index = task.try_make_index(&app_data.client).unwrap();
34+
35+
index.add_documents(&list_users, Some("id")).await?;
36+
}
37+
}
38+
39+
let index = app_data.client.get_index("users").await?;
40+
41+
let query = SearchQuery::new(&index).with_query(&query_string).build();
42+
43+
let results: SearchResults<User> = index.execute_query(&query).await?;
44+
45+
log::error!("{:#?}", results.hits);
46+
47+
let search_results: Vec<User> = results
48+
.hits
49+
.into_iter()
50+
.map(|hit| User {
51+
id: hit.result.id,
52+
email: hit.result.email,
53+
first_name: hit.result.first_name,
54+
last_name: hit.result.last_name,
55+
})
56+
.collect();
57+
58+
Ok(search_results)
59+
}
60+
}

0 commit comments

Comments
 (0)