Why GraphQL implements
keyword need to duplicate the fields, is that mandatory? Like the examples in the document:
enum Episode { NEWHOPE, EMPIRE, JEDI }
interface Character {
id: String
name: String
friends: [Character]
appearsIn: [Episode]
}
type Human implements Character {
id: String
name: String
friends: [Character]
appearsIn: [Episode]
homePlanet: String
}
type Droid implements Character {
id: String
name: String
friends: [Character]
appearsIn: [Episode]
primaryFunction: String
}
If yes, what is the underlying reasons?
Coz If I have to duplicate, if I change then i need to change everywhere...
A field is essentially an object-specific attribute that holds a value. The object's parent type defines which fields an object must have. Each field is set at definition to hold certain data types, such as String or Enum .
GraphQL works by sending operations to an endpoint. There are three types of operations: queries, mutations, and subscriptions.
The GraphQL API uses three main components that reside on the GraphQL server. These components are query, resolver, and schema. Server-side components allow parsing the queries coming from GraphQL client applications.
The GraphQLSchema object is the core of a GraphQL server When using any of these libraries, your development process is centered around a GraphQLSchema object, consisting of two major components: the schema definition. the actual implementation in the form of resolver functions.
Yes, this is mandatory according to the current spec:
The object type must include a field of the same name for every field defined in an interface.
It allows you to specify more precisely types of fields in the derived type. Fields can be changed to be not-null or to some specific subtype of an interface or a union. Taking your example, let's assume that humans are friends only with other humans and the same for droids. Then the following schema is valid.
interface Character {
id: String
name: String
friends: [Character]
appearsIn: [Episode]
}
type Human implements Character {
id: String
name: String
friends: [Human] # <- notice Human here
appearsIn: [Episode]
homePlanet: String
}
type Droid implements Character {
id: String
name: String
friends: [Droid!]! # <- specified Droid here + added not null
appearsIn: [Episode]
primaryFunction: String
}
The object field may include additional arguments not defined in the interface field (but any additional argument must not be required).
Check out the spec for more details: Object type validation
Yes it's mandatory. If it helps, think of it as analogous to Java classes and interfaces. The interfaces have the type signatures, but cannot have an implementation. It is in the classes where you write out all the implementation, and the type signatures get repeated. This gives you the ability to choose subtypes or covariant types in the types signatures, so they might not be exactly the same.
Now suppose you are creating a GraphQL schema with the JavaScript objects from graphql-js. The interfaces are simply field names and types. The Object Type definitions themselves have the "implementation," or the resolve
, resolveType
, and other properties that actually make it an executable schema.
Your example, however, uses the schema language instead, which has no "implementation" at all. So they pretty much are an exact repetition of one another. You don't necessarily need to spell it all out every time, you could use string interpolation to share parts of the interface.
const characterFields = `
id: String
name: String
friends: [Character]
appearsIn: [Episode]
`
const typeDefs = `
interface Character {
${characterFields}
}
type Human Implements Character {
${characterFields}
homePlanet: String
}
`
EDIT: Analogous to the Java comparison, the fields may not be exactly the same type. As RomanHotsiy pointed out, you can make the types non-nullable or use subtypes of polymorphic types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With