After successfully creating a sample Rust+GraphQL project using async-graphql and axum and visualizing something in the playground, the time has come to actually use data for queries.
I am using this for schema:
let schema = Schema::build(
Query,
EmptyMutation,
EmptySubscription
)
.data(user_data)
.finish();
where Query is:
pub(crate) struct Query;
where user_data is:
pub struct Users {
pub users: Vec<User>,
}
where User is (as a sample):
pub struct User {
id: u32,
name: String,
flag: u8
}
and everything gets loaded from a json file (before passing into schema).
Searching and finally reaching this database example, I could get the vector passed when creating the scheme like this:
#[Object]
impl Query {
async fn users(&self, ctx: &Context<'_>) -> Result<Option<Vec<User>>, String> {
let user_data = match ctx.data::<Users>() {
Ok(user_data) => user_data,
Err(err) => return Err(err.message.to_string()),
};
Ok(Some(user_data.users.clone()))
}
}
After I got the Error: error[E0277]: the trait bound User: OutputType
is not satisfied ^^^ the trait OutputType
is not implemented for User
…
Adding a bare:
impl OutputType for User {
}
lead, of course and understandable, to "error[E0046]: not all trait items implemented, missing: type_name
, create_type_info
, resolve
^^^ missing type_name
, create_type_info
, resolve
in implementation".
I see in the documentation what it is to be implemented.
The thing is, I have no idea what these are supposed to do nor how they are meant to be implemented (looking into it).
And I ask of you before going deeper trying to figure this implementation out: Is this the right way to load data in GraphQL, while not directly using a DB, or is there a simpler solution?
Gladly to edit for more information.
UPDATE
After trying migrating to a (mysql) DB approach, and solving the mapping like it is proposed here:
#[Object]
impl Query {
async fn users(&self, ctx: &Context<'_>) -> Result<Option<Vec<User>>, String> {
let pool = match ctx.data::<Pool>() {
Ok(result) => result,
Err(error) => return Err(error.message.to_string()),
};
let mut connection = match pool.get_conn() {
Ok(result) => result,
Err(error) => panic!("{}", error),
};
match connection.query_map(
"SELECT * FROM users",
|row: Row| { User::new_from_row(row) }
) {
Ok(result) => Ok(Some(result)),
Err(error) => return Err(error.to_string()),
}
}
it is still requiring the implementation of "OutputType"!
So I guess there is no way around this, but it strikes me very odd since there is nothing mentioned in the example of the first link about that. The example "Dog" struct is also just a simple one.
1
use async_graphql::*; #[derive(SimpleObject)] pub struct User { … } solved the issue…
yesterday