GraphQL SDL: GraphQL Schema Fields & Types - II #5

A brief introduction to GraphQL types such as Query type, Mutation type and more


In this post, you'll learn about:
  • Interfaces
  • Input Field
  • Query Type
  • Mutation Type
  • Subscription Type

  Image Credits: https://www.graph.cool/
Image Credits: https://www.graph.cool/

Interfaces

Like many type systems, GraphQL supports interfaces. An Interface is an abstract type that includes a certain set of fields that a type must include to implement the interface.

For example, you could have an interface Character that represents any character in the Star Wars trilogy:
interface Character { id: ID! name: String! friends: [Character] appearsIn: [Episode]! }

This means that any type that implements Character needs to have these exact fields, with these arguments and return types.

For example, here are some types that might implement Character:
type Human implements Character { id: ID! name: String! friends: [Character] appearsIn: [Episode]! starships: [Starship] totalCredits: Int } type Droid implements Character { id: ID! name: String! friends: [Character] appearsIn: [Episode]! primaryFunction: String }

You can see that both of these types have all of the fields from the Character interface, but also bring in extra fields, totalCredits, starships and primaryFunction, that are specific to that particular type of character.

Interfaces are useful when you want to return an object or set of objects, but those might be of several different types.
. . .

Input types

So far, we've only talked about passing scalar values, like enums or strings, as arguments into a field. But you can also easily pass complex objects.

This is particularly valuable in the case of mutations, where you might want to pass in a whole object to be created. In the GraphQL schema language, input types look exactly the same as regular object types, but with the keyword input instead of type:
input ReviewInput { stars: Int! commentary: String }

Here is how you could use the input object type in a mutation:
#mutation resolver
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) { createReview(episode: $ep, review: $review) { stars commentary } }
#Mutation variables { "ep": "JEDI", "review": { "stars": 5, "commentary": "This is a great movie!" } }
#Response { "data": { "createReview": { "stars": 5, "commentary": "This is a great movie!" } } }

The fields on an input object type can themselves refer to input object types, but you can't mix input and output types in your schema. Input object types also can't have arguments in their fields.

We will discuss it in more detail with an example in the next tutorial.
. . .

Query type

Most types in your schema will just be normal object types, but there are special within a schema such as Query:
schema { query: Query }

That means that the GraphQL service needs to have a Query type with Person and Planet fields:
type Query { person(id: Int!): Person planet(id: Int!): Planet }

Every GraphQL service has a query type and may or may not have a mutation type. These types are the same as a regular object type, but they are special because they define the entry point of every GraphQL query.
{
person (id:1) {
name
image
id
height
}
planet (id: 1) {
name
id
gravity
population
}
}

It's important to remember that other than the special status of being the "entry point" into the schema, the Query and Mutation types are the same as any other GraphQL object type, and their fields work exactly the same way.
. . .

Mutation type

Most types in your schema will just be normal object types, but there are special within a schema such as Mutation:
schema { mutation: Mutation }

That means that the GraphQL service needs to have a Mutation type with createPerson field:
type Mutation { createPerson(name: String!, age: Int!): Person }

Mutations follow the same syntactical structure as queries, but they always need to start with the mutation keyword. Here’s an example for how we might create a new Person.
mutation {
createPerson(name: "Bob", age: 36) {
name
id
age
}
}


. . .

Subscription type

Most types in your schema will just be normal object types, but there are special within a schema such as Subscription :
schema { subscription: Subscription }

That means that the GraphQL service needs to have a Mutation type with newPerson field:
type Subscription{ newPerson (): Person }

Subscriptions are written using the same syntax as queries and mutations. Here’s an example where we subscribe on events happening on the Person type:
subscription { newPerson { name age } }

After a client sent this subscription to a server, a connection is opened between them. Then, whenever a new mutation is performed that creates a new Person, the server sends the information about this person over to the client:
{
"data": {
"newPerson": {
"name": "Bob",
"age": 36,
"id": "7db71f51-2a6d-47d9-b261-879c41f293f0"
}
}
}

You can play around with below codesendbox to see how it works
  • first, subscribe for a new person in the first tab
  • create a new person from another tab

once a new person is created, it will be displayed on the newPerson subscription tab:
Generally, a schema is simply a collection of GraphQL types. However, when writing the schema for an API, there are some special root types:
type Query { ... }
type Mutation { ... }
type Subscription { ... }
. . .
In the next tutorials, we will look into the core concepts of GraphQL such as Query, mutation, variables and more



Never miss a post from Gufran Mirza, when you sign up for Ednsquare.