Introduction to GraphQL Schemas and Types
Tags: graphql, webdev, programming, javascript
Published: 2021-01-25 01:41:20

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

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.