This question already has an answer here:
-
Share common fields between Input and Type in GraphQL
2 answers
A very common use case in GraphQL is creating an object with a mutation, and receiving the exact same fields back, plus and ID returned by the database. Here's a related question asking about this.
My question is, how can this pattern be simplified to avoid repeated fields? I've tried reusing the input type as a fragment,
input ClientInput {
short_name: String
full_name: String
address: String
email: String
location: String
}
type Client {
id: String
...ClientInput
}
...but that failed with
Syntax Error: Expected Name, found ...
All the documentation and blog posts I've seen on Fragments always creates them on
an existing type. That means still repeating all but the ID field:
type Client {
_id: String
short_name: String
full_name: String
address: String
email: String
location: String
}
fragment ClientFields on Client {
short_name: String
full_name: String
address: String
email: String
location: String
}
input ClientInput {
...ClientFields
}
How is that any better?
Fragments are intended to be used client-side when composing queries. From the specification:
Fragments allow for the reuse of common repeated selections of fields, reducing duplicated text in the document.
The intent behind fragments is that you may have any number of saved queries that query the same type -- you don't want to have to update 20 different queries if the schema changes or you decide you don't need a certain field anymore.
A similar mechanism for allowing fields to be shared between a Type and an Input Type server-side just does not exist. This is likely largely by design because even though a Type field and an Input Type field both have some kind of type
, they may have other properties. For example, Input Type fields can have a default value, while that property does not exist for a Type field. Similarly, Type fields have resolvers and arguments, which Input Type fields do not.
If you really want to keep things DRY, there may be workarounds available, depending on what kind of GraphQL server you're running. If it's a GraphQL.js server that uses a schema created from one or more SDL strings, for example, you can just use template literals:
const sharedClientFields = `
short_name: String
full_name: String
address: String
email: String
location: String
`
const schema = `
type Client {
_id: String
${sharedClientFields}
}
type ClientInput {
${sharedClientFields}
}
`