Experience GraphQL Summit 2024: Watch On-demand →
Experience GraphQL Summit 2024: over 45+ technical sessions, real-world success stories, next-gen product demos and more. Watch On-demand →
"Is it THIS? Or is it THAT?"
To understand what something is, we often consider its characteristics: what makes it unique? What sets it apart from other things? What category could it belong to?
Types bring order into the growing world of data. Like big labeled boxes, they let us sift through the mess and logically sort "text" away from "numbers", and "timestamps" away from "unique identifiers."
But grouping things into their types comes with more than just a label telling us what's inside. When we understand the type of data we're working with, we know what we can and can't do with it while programming: we can do certain things with numbers that we can't with text, for example! The data type we work with determines the kinds of operations and transformations we can perform on it.
GraphQL uses a type system to help us understand what kind of a thing a value is. A type system is a set of rules that defines the possible types of data that we can work with in a programming language. Working within these rules helps us organize our data and how we're using it, and it also makes it easier for us to represent relationships between different types, as we'll see in this article.
We define the specific types for the data we want to query and work with in a document called our GraphQL schema, which we'll explore in an upcoming section. But to get started, let's dig into the two main categories of types in GraphQL: object types and scalar types.
Object types represent something with properties, or fields, that we want to retrieve data for. Think of these as characteristics that we want to know about, or the details that make the object important for whatever we're building.
A fruit stall at a farmer's market could represent Fruit
as an object type, and define fields such as name
, quantity
, price
and hasEdibleSeeds
.
With these fields, the Fruit
type could represent a lot of different kinds of fruit beyond just blueberries. That's because the Fruit
type by itself is non-specific: it doesn't automatically represent a particular kind of fruit, but rather serves as a broader category that many different kinds of fruit could fit into. The fields name
, quantity
, averageWeight
, price
, and hasEdibleSeeds
can all be applied to fruit varieties and, in turn, hold different values.
To define an object type, we use the type
keyword, followed by the name we'd like to use. Next, we open up a pair of curly braces; this is where we'll end up defining all of the fields that make up the Fruit
type.
type Fruit {# a Fruit object has a name, quantity, averageWeight, price, and hasEdibleSeeds}
We can think of the Fruit
type as a kind of structure: it defines the requirements that anything that calls itself "fruit" should follow. It's like a big label we can stick on anything that fits the qualifications; and it also gives us a clear idea of what's not included in the type.
But what about the actual type of data being provided for each field? How do we know that name
returns a word like "blueberry", and that quantity
returns some kind of number we can do calculations on? For this, we have a separate category of types: scalar types.
Check out the Fruit
type below. Inside of its curly braces, we'll find a name
property.
type Fruit {name: String}
Right now, this is the only field the Fruit
type has; it lets us know that name
is a bit of data we can expect to find on objects categorized as Fruit
.
You'll notice that it also defines something else: name
returns a type called String
.
String
is one of several scalar types we can use to describe the kind of data a field returns. Scalar types represent primitive values—they don't contain fields, like object types do—and we use them to categorize values such as text, numbers, and true or false, along with a few others.
The available scalar types in GraphQL are String
, Int
, Float
, Boolean
and ID
.
We can see a few of these in action by filling out the remaining fields on the Fruit
type—and visualizing them applied to an actual fruit that Fruit
could represent.
Using this example, we can gather a few clues about what each scalar type is responsible for:
String
represents words, letters, and charactersInt
and Float
are used to represent numeric valuesBoolean
represents the value true
or the value false
In the next section, we'll explore each of the scalar types in greater detail, and learn how to put them to work for us in a query.
In order to query a GraphQL service for any kind of data at all, it needs to define a special kind of object type called Query
. This type defines how, and what, we can read from a service, and like the other types we've talked about, it lives in a GraphQL service's schema.
Query
is considered a "root" type because it acts as the entry point to everything we're allowed to query for. Asking for data without it would be a lot like trying to enter a warehouse without a door. In the same way that a front door lets us into a building with hallways leading to different rooms, the Query
type provides us with the possible query pathways we can use to get to data.
Implemented in GraphQL, the Query
type looks like any other object type with a name and fields.
type Query {mostPopularFruit: Fruit}
The Query
type's fields are what we use to send specific requests for data. In this example, Query
has just one field, mostPopularFruit
, which returns a Fruit
object when queried. We'll see how to plug our types together to query for actual data in an upcoming section on Querying between Types.
About
GraphQL.com is maintained by the Apollo team. Our goal is to give developers and technical leaders the tools they need to understand and adopt GraphQL.
GraphQL.com 2024