Continuing Part one on the GraphQL Schema Definition Language, this article goes on to cover the concepts used to define the GraphQL Schema
1. Interfaces
- Like the concept of Interface in other languages, in GraphQL, an Interface is an asbstract type can consist of a certain set of fields whose types when implementing it must also include those fields.
- For example, you have a
Character
interface that represents any character in Star Wars1234567<span class="token keyword">interface</span> <span class="token class-name">Character</span> <span class="token punctuation">{</span><span class="token attr-name">id</span> <span class="token punctuation">:</span> ID <span class="token operator">!</span><span class="token attr-name">name</span> <span class="token punctuation">:</span> String <span class="token operator">!</span><span class="token attr-name">friends</span> <span class="token punctuation">:</span> <span class="token punctuation">[</span> Character <span class="token punctuation">]</span><span class="token attr-name">appearsIn</span> <span class="token punctuation">:</span> <span class="token punctuation">[</span> Episode <span class="token punctuation">]</span> <span class="token operator">!</span><span class="token punctuation">}</span>
Any type of ImplementsCharacters
must have all of the above fields with the same parameters or the same type. - For example, the types six here can implement
Character
1234567891011121314151617<span class="token keyword">type</span> <span class="token class-name">Human</span> <span class="token keyword">implements</span> <span class="token class-name">Character</span> <span class="token punctuation">{</span><span class="token attr-name">id</span> <span class="token punctuation">:</span> ID <span class="token operator">!</span><span class="token attr-name">name</span> <span class="token punctuation">:</span> String <span class="token operator">!</span><span class="token attr-name">friends</span> <span class="token punctuation">:</span> <span class="token punctuation">[</span> Character <span class="token punctuation">]</span><span class="token attr-name">appearsIn</span> <span class="token punctuation">:</span> <span class="token punctuation">[</span> Episode <span class="token punctuation">]</span> <span class="token operator">!</span><span class="token attr-name">starships</span> <span class="token punctuation">:</span> <span class="token punctuation">[</span> Starship <span class="token punctuation">]</span><span class="token attr-name">totalCredits</span> <span class="token punctuation">:</span> Int<span class="token punctuation">}</span><span class="token keyword">type</span> <span class="token class-name">Droid</span> <span class="token keyword">implements</span> <span class="token class-name">Character</span> <span class="token punctuation">{</span><span class="token attr-name">id</span> <span class="token punctuation">:</span> ID <span class="token operator">!</span><span class="token attr-name">name</span> <span class="token punctuation">:</span> String <span class="token operator">!</span><span class="token attr-name">friends</span> <span class="token punctuation">:</span> <span class="token punctuation">[</span> Character <span class="token punctuation">]</span><span class="token attr-name">appearsIn</span> <span class="token punctuation">:</span> <span class="token punctuation">[</span> Episode <span class="token punctuation">]</span> <span class="token operator">!</span><span class="token attr-name">primaryFunction</span> <span class="token punctuation">:</span> String<span class="token punctuation">}</span>
All three types have all the fields from theCharacter
interface, and also have additional fields liketotalCredits
,starships
,primaryFunction
help define specific types of Character. - Interfaces are useful when you want to return an object or a set of objects, but they have different fields.
- For example, the following query will generate an errorQUERY DEFINITION1234type Query {hero(episode: Episode): Character}
CLIENT CALL QUERY123456789<span class="token keyword">query</span> HeroForEpisode <span class="token punctuation">(</span> <span class="token variable">$ep</span> <span class="token punctuation">:</span> Episode <span class="token operator">!</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>hero <span class="token punctuation">(</span> <span class="token attr-name">episode</span> <span class="token punctuation">:</span> <span class="token variable">$ep</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>name<span class="token operator">...</span> <span class="token keyword">on</span> <span class="token class-name">Droid</span> <span class="token punctuation">{</span>primaryFunction<span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span>
VARIABLES1234<span class="token punctuation">{</span><span class="token property">"ep"</span> <span class="token operator">:</span> <span class="token string">"JEDI"</span><span class="token punctuation">}</span>
RESULT1234567891011121314<span class="token punctuation">{</span><span class="token property">"errors"</span> <span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><span class="token property">"message"</span> <span class="token operator">:</span> <span class="token string">"Cannot query field "primaryFunction" on type "Character". Did you mean to use an inline fragment on "Droid"?"</span> <span class="token punctuation">,</span><span class="token property">"locations"</span> <span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><span class="token property">"line"</span> <span class="token operator">:</span> <span class="token number">4</span> <span class="token punctuation">,</span><span class="token property">"column"</span> <span class="token operator">:</span> <span class="token number">5</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span> - The
hero
field returns aCharacter
type, it can beHuman
orDroid
depending on theepisode
variable. In the above query, you can only specify to return fields that exist in theCharacter
interface, so there is noprimaryFunction
- To request that the fields be returned in a specific object type, use inline fragments
2. Union types
- For example12<span class="token keyword">union</span> <span class="token class-name">SearchResult</span> <span class="token operator">=</span> Human <span class="token operator">|</span> Droid <span class="token operator">|</span> Starship
- Whenever we return a type of
Search Result
in the schema, this SearchResult can be aHuman
,Droid
, or aStarship
. The members of a union type need to be of a particular type of object, not an interface or another union - When the client side queries a field that returns a union type of
SearchResult
, we need to use the inline fragment to be able to query any field.CLIENT QERRY123456789101112131415161718<span class="token punctuation">{</span>search <span class="token punctuation">(</span> <span class="token attr-name">text</span> <span class="token punctuation">:</span> <span class="token string">"an"</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>__typename<span class="token operator">...</span> <span class="token keyword">on</span> <span class="token class-name">Human</span> <span class="token punctuation">{</span>nameheight<span class="token punctuation">}</span><span class="token operator">...</span> <span class="token keyword">on</span> <span class="token class-name">Droid</span> <span class="token punctuation">{</span>nameprimaryFunction<span class="token punctuation">}</span><span class="token operator">...</span> <span class="token keyword">on</span> <span class="token class-name">Starship</span> <span class="token punctuation">{</span>namelength<span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span>
RESULT12345678910111213141516171819202122<span class="token property">"data"</span> <span class="token operator">:</span> <span class="token punctuation">{</span><span class="token property">"search"</span> <span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><span class="token property">"__typename"</span> <span class="token operator">:</span> <span class="token string">"Human"</span> <span class="token punctuation">,</span><span class="token property">"name"</span> <span class="token operator">:</span> <span class="token string">"Han Solo"</span> <span class="token punctuation">,</span><span class="token property">"height"</span> <span class="token operator">:</span> <span class="token number">1.8</span><span class="token punctuation">}</span> <span class="token punctuation">,</span><span class="token punctuation">{</span><span class="token property">"__typename"</span> <span class="token operator">:</span> <span class="token string">"Human"</span> <span class="token punctuation">,</span><span class="token property">"name"</span> <span class="token operator">:</span> <span class="token string">"Leia Organa"</span> <span class="token punctuation">,</span><span class="token property">"height"</span> <span class="token operator">:</span> <span class="token number">1.5</span><span class="token punctuation">}</span> <span class="token punctuation">,</span><span class="token punctuation">{</span><span class="token property">"__typename"</span> <span class="token operator">:</span> <span class="token string">"Starship"</span> <span class="token punctuation">,</span><span class="token property">"name"</span> <span class="token operator">:</span> <span class="token string">"TIE Advanced x1"</span> <span class="token punctuation">,</span><span class="token property">"length"</span> <span class="token operator">:</span> <span class="token number">9.2</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span><span class="token punctuation">}</span> - The __typename field is a String that helps you to distinguish between object types on the Client
- In this example, since
Human
andDroid
implement the same interfaceCharacter
, you can query the common fields of these 2 object types in one place without repeating the same fields for each type, for example below The result is as above:12345678910111213141516171819<span class="token punctuation">{</span>search <span class="token punctuation">(</span> <span class="token attr-name">text</span> <span class="token punctuation">:</span> <span class="token string">"an"</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>__typename<span class="token operator">...</span> <span class="token keyword">on</span> <span class="token class-name">Character</span> <span class="token punctuation">{</span>name<span class="token punctuation">}</span><span class="token operator">...</span> <span class="token keyword">on</span> <span class="token class-name">Human</span> <span class="token punctuation">{</span>height<span class="token punctuation">}</span><span class="token operator">...</span> <span class="token keyword">on</span> <span class="token class-name">Droid</span> <span class="token punctuation">{</span>primaryFunction<span class="token punctuation">}</span><span class="token operator">...</span> <span class="token keyword">on</span> <span class="token class-name">Starship</span> <span class="token punctuation">{</span>namelength<span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span>
Note: Thename
field must still be specified to Starship becauseStarship
not aCharacter
3.Input types
- So far, we’ve only talked about passing a field argument of type scalar like enums or strings. However, you can pass the argument to a complex object. This is extremely useful when you want to pass an entire object to create something.
- In GraphQL SDL, input types look like common object types but with keyword input instead of type12345<span class="token keyword">input</span> ReviewInput <span class="token punctuation">{</span><span class="token attr-name">stars</span> <span class="token punctuation">:</span> Int <span class="token operator">!</span><span class="token attr-name">commentary</span> <span class="token punctuation">:</span> String<span class="token punctuation">}</span>
- Example using input type in a mutationMUTATION DEFINITION1234567<span class="token keyword">mutation</span> CreateReviewForEpisode <span class="token punctuation">(</span> <span class="token variable">$ep</span> <span class="token punctuation">:</span> Episode <span class="token operator">!</span> <span class="token punctuation">,</span> <span class="token variable">$review</span> <span class="token punctuation">:</span> ReviewInput <span class="token operator">!</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>createReview <span class="token punctuation">(</span> <span class="token attr-name">episode</span> <span class="token punctuation">:</span> <span class="token variable">$ep</span> <span class="token punctuation">,</span> <span class="token attr-name">review</span> <span class="token punctuation">:</span> <span class="token variable">$review</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>starscommentary<span class="token punctuation">}</span><span class="token punctuation">}</span>
VARIABLES12345678<span class="token punctuation">{</span><span class="token property">"ep"</span> <span class="token operator">:</span> <span class="token string">"JEDI"</span> <span class="token punctuation">,</span><span class="token property">"review"</span> <span class="token operator">:</span> <span class="token punctuation">{</span><span class="token property">"stars"</span> <span class="token operator">:</span> <span class="token number">5</span> <span class="token punctuation">,</span><span class="token property">"commentary"</span> <span class="token operator">:</span> <span class="token string">"This is a great movie!"</span><span class="token punctuation">}</span><span class="token punctuation">}</span>
RESULT123456789<span class="token punctuation">{</span><span class="token property">"data"</span> <span class="token operator">:</span> <span class="token punctuation">{</span><span class="token property">"createReview"</span> <span class="token operator">:</span> <span class="token punctuation">{</span><span class="token property">"stars"</span> <span class="token operator">:</span> <span class="token number">5</span> <span class="token punctuation">,</span><span class="token property">"commentary"</span> <span class="token operator">:</span> <span class="token string">"This is a great movie!"</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span>
4. Conclusion
- Over two parts of this topic, I have presented the concepts used in Schema Difinition Language. I believe these concepts are enough for you to define your own basic schema. Hope the article is useful for you
- Reference source