Categories
GraphQL

Introduction to GraphQL Schemas and Types

Spread the love

GraphQL is a query language for our API and a server-side runtime for running queries by using a type system for our data.

In this article, we’ll look at the GraphQL type system and how it describes what data can be queried.

Schemas and Types

GraphQL requests are about selecting fields on objects.

In a query, we have a root object, then we select a field from that and fields below that level if it exists all the way to the bottom level.

For example, if we have the query:

{
  person {
    name
  }
}

Then we get something like:

{
  "data": {
    "person": {
      "name": "Jane"
    }
  }
}

as the response.

A GraphQL query closely matches the result so we can predict what the query will return without knowing that much about the serve.

But it’s still useful to have an exact description of data we can ask for.

This is where explicit types are useful.

Type language

GraphQL services can be written in any language. Therefore, types have to be defined in a language-agnostic way.

Object types and fields

We can define a GraphQL data type as follows:

type Person {
  name: String!
  addresses: [Address!]!
}

In the code above, we created a new type with the type keyword. In the type, we have the name field, which is String , and addresses , which is an array of Address es, which is another type.

String is a built-in scalar type. The exclamation marks mean the field is not nullable. Therefore, String! is a non-nullable string.

[Address!]! is an array of Address objects. It’s also non-nullable, so we can always expect an array with zero or more items when we query for addresses . Since Address! is also non-nullable, we can always expect every item of the array to be an Address object.

Arguments

Every field of a GraphQL object type can have zero or more arguments.

For example, we can write the following:

type Person {
  name: String!
  height(unit: HeightUnit = METER): Float
}

In the code above, we have the height field in the Person that takes a unit as the argument. unit is of type HeightUnit which is set to METER by default.

height returns a Float.

The Query and Mutation types

There’re 2 types that are special within a schema. They’re Query and Mutation .

Every GraphQL service has a query type and may or may not have an mutation type.

These types are the same as any other object type, but they’re special because they define the entry point of every GraphQL query.

If we have a query like the following:

query {
  person {
    name
  }
  robot(id: "2000") {
    name
  }
}

Then the GraphQL service needs to have the query type with the person and robot fields:

type Query {
  person(name: String): Person
  robot(id: ID!): Robot
}

We define mutation types the same way. We define fields on the Mutation type and those are available as the root mutation fields we can call in our query.

Scalar types

Scalar fields are what all object types contain in the end. They’re the most basic types of fields.

GraphQL comes with the following scalar types out of the box:

  • Int — a signed 32-bit integer
  • Float — a signed double-precision floating-point value
  • String — a UTF-8 character sequence
  • Boolean — true or false
  • ID — a unique identifier that used for fetching an object or as the key for a cache. It’s serialized the same way as a String but it’s not intended to be human-readable

Most GraphQL service implementations also let us specify custom scalar types.

We can define one as follows:

scalar Date

Then it’s up to use to decide how to serialize, deserialize and validate them.

Enumeration types

Enum types are special types of scalar that are restricted to a particular set of allowed values.

It lets us validate that any argument of the type is one of the allowed values.

Also, it communicates through the type system that a field will always be one of a finite set of values.

We can define an enum as follows:

enum Fruit {
  APPLE
  ORANGE
  GRAPE
}

Then if we have Fruit , we expect it to be either APPLE, ORANGE or GRAPE .

Conclusion

We can define types so that we can validate the data that’s submitted to the GraphQL server.

To do this, we create a type with the type keyword if it’s an object type.

We can also create scalar types which are the most basic types that can be included in other types or referenced directly. We can define them with the scalar keyword.

To define a type with fixed values, we can define an enum type with a few possible constant values.

The exclamation mark indicates that a type is not nullable.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *