Description
Hi,
I'm facing a weird issue about the input types generated by the GraphQL macro.
Lets say I already have the CardInfo
type in my codebase (on the server side), and I use the CardInfo
type in my _schema.graphql
:
#[derive(/*... */, SimpleObject, InputObject)]
#[graphql(input_name = "CardInfosInput")]
pub struct CardInfos {
// ...
};
_schema.graphql
# ...
type MutationRoot {
createCard(card: CardInfos!): CardId!
}
# ...
When I use a build script to generate a sdl back from this _schema.graphql
which is in a different crate, it creates both a CardInfosInput
input and a CardInfo
type :
build.rs
let schema = Schema::build(QueryRoot {}, MutationRoot {}, SubscriptionRoot {}).finish();
let mut file = BufWriter::new(File::create(&generated_path)?);
writeln!(&mut file, "{}", schema.sdl())?;
server_sdl.graphql
(the generated one)
type CardInfos {
fullName: FullName!
jobTitle: JobTitle!
# ...
}
input CardInfosInput {
fullName: FullName!
jobTitle: JobTitle!
# ...
}
Which forces me to use ...Input
types in my GraphQL operations definitions
createCard.graphql
mutation CreateCard($card: CardInfosInput!) {
createCard(card: $card)
}
This mutation is merged to the MutationRoot, and is defined as such :
#[derive(GraphQLQuery)]
#[graphql(schema_path = "server_sdl.graphql", query_path = "src/queries/createCard.graphql", response_derives = "Debug")]
pub struct CreateCard;
However during the implementation of the resolver of such operations, I figured out there was no way to convert X
to XInput
types using something like a From
or Into
trait, in order to only write something like :
pub async fn create_card(state: GraphqlState, card: CardInfos) -> anyhow::Result<CardId> {
let schema = get_schema();
let vars = create_card::Variables { card: card.into() };
// ....
}
impl From<CardInfos> for crate::queries::create_card::CardInfosInput {
fn from(value: CardInfos) -> Self {
Self {
full_name: value.full_name,
job_title: value.job_title,
// ...
}
}
}
Furthermore, when using nested types I have to write more and more boilerplate.
Is there a way to avoid doing such a thing ? Or maybe could this macro expansion behavior be improved in any way ?
The problem can be summarized as follows :
(server) (client)
StructA => StructAInput => SDL => StructA / StructInputA
Is there a way to reuse backend structs ?
Thanks in advance !