The backbone of GraphQL’s structure as a query language is its type system. The community has put together fantastic and thorough documentation and tutorials on GraphQL types and how to begin structuring your own schema, but the purpose of this post is to give you a quick overview so that the structure seems a bit less daunting if you’re taking the autodidactic approach (as I did).
The first types you’ll come across when learning to define your schema and query your API are operation types (often referred to as “root” types), which are: query, mutation, and subscription. You can think of a query like a GET request in REST, and a mutation like a combination of POST, PUT/PATCH, and DELETE. Subscriptions allow the server to send a client data based on the occurrence of a specific event.
When defining your schema, you’ll usually be creating a series of object types composed of multiple fields. Here’s an example of an object type I created for an AWS app I was building last week:

Let’s break that down. The field value types (yes, they’re also types!); ID, String, Boolean, Int (integer), and Float are called scalar types. Scalar types can hold a single value and the above list comes built in. In most service implementations, there is also support for a Date type; and in some, an Enum (enumeration) type, which is a particular type of scalar restricted to defined values.
The exclamations on fields 2-4 imply that the fields are non-nullable, meaning that an object must contain values for those fields when it is created. This also means that those fields will never return null when queried.
I won’t cover these for now, but other types worth reading about are interfaces and unions (for cases in which types share common fields) and inputs (complex, non-scalar type that can be passed into another object within a single field).
Sources and further reading:

