Reputation: 2821
If I have a set of field that is common to multiple types in my GraphQL schema, is there a way to do something like this?
type Address {
line1: String
city: String
state: String
zip: String
}
fragment NameAndAddress on Person, Business {
name: String
address: Address
}
type Business {
...NameAndAddress
hours: String
}
type Customer {
...NameAndAddress
customerSince: Date
}
Upvotes: 43
Views: 29307
Reputation: 21309
You can, but GraphQL won't let you make a fragment between 2 types unless you specify into the schema that those types are sharing the same properties. To do so, you have to use an interface. You will then be able to build a fragment of this interface on the client side.
Server side schema:
interface NameAndAddress {
name: String
address: Address
}
type Address {
line1: String
city: String
state: String
zip: String
}
type Business implements NameAndAddress {
# by design you have to write those properties again
name: String
address: Address
hours: String
}
type Customer implements NameAndAddress {
name: String
address: Address
customerSince: Date
}
Then on your client
# define a fragment on the interface
fragment NameAndAddress on NameAndAddress {
name: String
address: Address
}
# you can then get the fields as follow
query {
business {
...NameAndAddress
}
customer {
...NameAndAddress
}
}
Upvotes: 8
Reputation: 1699
Don't know if it was not available at this question time, but I guess interfaces should fit your needs
Upvotes: 3
Reputation: 84687
Fragments are only used on the client-side when making requests -- they can't be used inside your schema. GraphQL does not support type inheritance or any other mechanism that would reduce the redundancy of having to write out the same fields for different types.
If you're using apollo-server
, the type definitions that make up your schema are just a string, so you can implement the functionality you're looking for through template literals:
const nameAndAddress = `
name: String
address: Address
`
const typeDefs = `
type Business {
${nameAndAddress}
hours: String
}
type Customer {
${nameAndAddress}
customerSince: Date
}
`
Alternatively, there are libraries out there, like graphql-s2s, that allow you to use type inheritance.
Upvotes: 21