GraphQL.com

LearnTutorialsCommunityEventsFAQs  

Table of contents

    GRAPHQL BASICS

  • What is GraphQL?
  • The Query
  • Introducing Types
  • Scalars, Objects, and ListsThe String typeThe Int typeThe Float typeThe Boolean typeThe ID typeThe List type
  • Nullability
  • Querying between Types
  • Schema
  • Enums
  • Interfaces & Unions
  • Arguments
  • Mutations


Try GraphOS  
The GraphQL developer platform

Scalars, Objects, and Lists

GraphQL types are great for consistency (we know what data to expect from a particular type) and efficiency (types can reference other types, which we'll see soon). To maximize their power, the types that we create and maintain should reflect what's needed from our data and how it's being used.

In this section, we'll dive deeper into three fundamental types that let us define our data and express relationships: scalar types, object types, and the List type.

We'll refer to the following Fruit type as we explore each of the scalar types.

type Fruit {
name: String
quantity: Int
price: Int
averageWeight: Float
hasEdibleSeeds: Boolean
}

The String type

If we ask for the fruit's name, we expect a specific word or label that will help us identify the particular fruit we're looking at. In GraphQL, we represent this kind of data—characters and text, either in single words or strung together in sentences—using the scalar type String.

A sticker that reads 'Hello my name is Banana'.

When a field is "typed" as a String, the text it hands back as its value should be written with Unicode characters contained in quotation marks. Here, we can understand "characters" as the units of human writing systems (like the letters of the Latin alphabet, which English uses).

The Int type

There are three fields on the Fruit type that return number values, but altogether we're actually representing two different kinds of data. Let's start by taking a look at the quantity and price fields.

The quantity field, which keeps track of how many of an item are in stock, shouldn't be a fraction (we won't sell half a blueberry, or maintain a stock of 13.33 pears). For this reason, valid values of the quantity field should be represented by the scalar type Int.

The Int type, short for "integer", is ideal for this use case as it's used to represent 32-bit numbers: positive or negative non-fractional numbers, including zero, that can be written in binary using up to 32 digits of 1s and 0s.

So if the Int type is used to represent non-fractional numbers, why would we use it to represent the type of data we expect the price field to provide? After all, we would probably expect an item's price to look something like this: 2.99.

Well, it's actually not the wisest practice to use fractional numbers, or decimals, when storing currency data. Most modern systems will represent monetary amounts like an item's cost in terms of the currency's smallest indivisible component—such as a penny! This lets us represent prices in a form that won't result in lost data as more and more computations are done on the number. In this case, instead of 2.99, the equivalent amount in pennies would be 299!

Check out the important note in the following section on the Float type to learn more.

The Float type

In contrast to quantity and price, the averageWeight field on the Fruit type is an actual decimal—or floating point—number! Numbers represented by the Float type allow for more granular fluctuations in value as they increase or decrease. The weight of a pear in kilograms—0.18, on average—differs considerably from the weight of a single blueberry at 0.0005 kilograms! Without this ability to represent fractional numbers, we couldn't visualize these very precise differences. We'd either need to truncate both items' averageWeight to 0 kilograms, or inflate them both to 1! Not terrifically accurate. To represent numbers of this type, we'll use the scalar type Float.

The Boolean type

The last field (hasEdibleSeeds) on the Fruit type should provide something like a "yes" or "no" answer to whether a particular fruit type contains edible seeds. We've given this field a Boolean type, which tells us that we can expect a true or false value when we query a fruit type's hasEdibleSeeds field. There is no halfway point between true and false—no "maybe" or "almost"—so we can think of Boolean fields like light switches, because we toggle them between two discrete values much like "on" and "off".

An image with a question: "Can you eat the seeds?" alongside a lemon (whose seeds are safe to eat) and a pear (whose seeds are not).

The ID type

GraphQL provides another scalar type out of the box that we haven't yet used here. It's the ID type, and like any ID (such as your driver's license or passport), its purpose is to help us identify something unique. When an object type includes a field with type ID, we can use it to definitively specify which object we're talking about, particularly if other fields—even the seemingly unique name field on our Fruit type—have the potential to be the same!

Two Fruit types with different IDs, which let us be sure which one is an banana, and which is an orange.

We can supplement our Fruit type with an ID simply by defining a new field and setting it as type ID. A standard name for this field is id, because many frameworks working with GraphQL know how to handle it by default.

type Fruit {
id: ID
name: String
quantity: Int
price: Int
averageWeight: Float
hasEdibleSeeds: Boolean
}

The Apollo Sandbox below includes an operation that currently requests the name and quantity fields for mostPopularFruit. Use the left-hand panel titled "Documentation" to explore the Fruit type. YOu can also use it to test out adding other fields, then run the query to see what data appears in the Response panel.

The Documentation panel in Apollo Sandbox lets you explore all of the types of fields in a GraphQL service's schema. You can collapse or reopen it by toggling the two arrows at the top of the panel.

As you can see from the fields we've discussed on the Fruit type, we expect fields denoted with a scalar type to hand back a single, self-contained value such as a name, a line of text in quotations, a number, or a true/false value.

This works well in a lot of cases: sometimes we only need a single piece of data for each field. But GraphQL also gives us a way to represent that a field should have the ability to return more than one item. We can achieve this using the List type.

The List type

The List type is considered a "wrapping type" in GraphQL, because unlike the scalar types we've seen so far, we don't use a particular label or keyword to denote a field as a list; instead, we use square brackets ([]) to enclose the name of the data type the list contains.

nutrients: [String]

This means that a field can return more than one item—but it doesn't have to! A list might contain just one item, or even no items at all. But when an object has multiple bits of data that relate to just one of its fields, lists can be particularly useful.

A list of nutrients, ("Dietary Fiber", "Vitamin C", "Manganese") strung out behind the blueberry they relate to.

Let's add the nutrients field we saw above to the Fruit type. This new field allows us to express more than the single most prevalent vitamin or mineral that the fruit contains. We might use it to provide information about the three most concentrated nutrients in a fruit, and let this drive customers' purchasing decisions.

type Fruit {
id: ID
name: String
quantity: Int
price: Int
averageWeight: Float
hasEdibleSeeds: Boolean
nutrients: [String]
}

Try it out! Click into mostPopularFruit from the Documentation panel, then add the nutrients field to the query below.

Up Next: Nullability  

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