Table of contents


  • What is GraphQL?
  • The QueryQuerying with types and fieldsQueries in GraphQLRunning a query
  • Introducing Types
  • Scalars, Objects, and Lists
  • Nullability
  • Querying between Types
  • Schema
  • Enums
  • Interfaces & Unions
  • Arguments
  • Mutations

Try GraphOS  
The GraphQL developer platform

The Query

Queries lie at the heart of GraphQL. Like a request or a question, queries can be used to get answers about something specific.

More technically, queries are used to retrieve data. The query languages we use in computers and on the internet can define their own unique way of asking for data, but they share a common goal: to request information.

When we write and run a GraphQL query, we're sending a structured request for data from a GraphQL API. The "structure" part of GraphQL is what allows us to write fewer, more precise requests to get all the data we need in one go. And it just takes a few core pieces: types and fields.

Querying with types and fields

We use a system of types and fields to organize and write our GraphQL queries. Types let us define what we want information about, and fields let us specify the individual properties on the type. This lets us get really detailed with our request: we can ask for lots of things, or just one.

Let's ask an example question—or query—to see these pieces at work.

"How much does the fruit cost?"

In this example, we can imagine the type of thing we're asking about as the "fruit". It's the subject that we want specific information for. As a type of thing in general, fruit could have many properties for us to learn about, but here we're asking for just one: the cost of the fruit, or its price.

With Fruit as our type, we can see how its price could exist as one of its fields.

A banana accompanied by two labels, one indicating it's a Fruit type, the other that it has a field called price.

Fields let us provide specific information about what makes up a type. A market representing its products as types might sell several kinds of fruit, and want to keep track of different information like name, price, and quantity available. The field values for each kind of fruit can differ, but they belong to the same type and share the same fields.

Three different kinds of fruit, represented individually as instances of the Fruit type with a name, price, and quantity.

In GraphQL, this Fruit type is considered an Object Type. When we need to represent a new kind of fruit, the type gives us a standard way to organize a fruit's fields and corresponding values so that we can access and use them.

  What makes up an object type?

How we define types—where we draw boundaries around the categories they work with—depends on how we want to use the data. In general, a type should define a recognizable category of things with common properties. In our case, we can have many different kinds of fruit that can be described using the same fields, even if their individual property values differ.

Queries in GraphQL

How do we actually ask for data using our types and fields with GraphQL?

To query for the kind of fruit data that we've described, we need a GraphQL service that's set up to understand what a Fruit type is and which fields it has. The service includes this information in a document called the schema, which outlines all the things we're allowed to ask the service for.

  What goes into a schema?

The schema is our source of truth when working with a GraphQL service. And in order to send queries to a service, we need its schema to include a very special type: the Query type.

The Query type is a lot like the Fruit type we've discussed, but its job is more important: it acts like the front door to a GraphQL service. The fields on the Query type define what specifically we can ask the service for. It's not enough to know that a Fruit type exists: the Query type is responsible for setting up the pathway to access it!

In this way, the Query type defines a list of everything we're allowed to ask for from a service. We can pick and choose from its fields to ask for different types of data, and it tells us what we can expect as a response.

A signboard representing the Query type contains directions for querying different types, such as fruit, vegetables, and cheeses.

Our queries can use any combination of the fields on the Query type to ask for more data about all available fruits, vegetables, or cheeses—but we can't ask the service for anything else (even if we know that they have chocolate in the backroom). We have to use the entry points that the Query type gives us to get our hands on some data.

Running a query

Let's return to our question about the price of the fruit at a market and see how it can be represented as a GraphQL query.

query GetFruitPrices {
fruits {

This query syntax begins with the query keyword, followed by an operation name that describes the request's purpose—like GetFruitPrices.

Finally, we open a pair of curly braces, where the remainder of the request is specified. Here we're asking for fruits. This is one of the fields on the Query type, so we can use it as our entry point into the service's data.

A signboard representing the Query type, alongside a question about the cost of one of the types.
  What makes up the Query type?

We know what kind of data the fruits field will return, and the additional fields we can ask about. Specifically, we can include the price field to help us answer our question.

Let's actually send our request to a GraphQL service that specializes in fruit! Below, you'll find an Apollo Sandbox. This is an environment where you can connect to a GraphQL service, see what types and fields it uses, and even send queries to receive actual data!

Try it for yourself by clicking the GetFruitPrices button in the Sandbox below.

Try it out!

You should see a response with the following shape on the right side of the Sandbox:

"data": {
"fruits": [
{ "price": 44 },
{ "price": 2 },
{ "price": 79 }

The response contains the same fruits key that we specified. The value we get back is an array that contains three unique objects. Each of these objects has a price key with a numeric value. The GraphQL service responded with a JSON object that matches the shape of our request; for each individual fruit, we can easily see the corresponding price.

But even when we inspect our response data, we can't be sure which fruit each price refers to. That's because the response includes only the data for the fields we chose—we asked exclusively for the price, not the corresponding name! This is actually one of the most powerful benefits of using GraphQL: we can query for exactly the data we need by picking the fields on the types we're interested in.

Test yourself in the challenge below. How can we fetch not only a fruit's price, but its name as well? Give it a try in the Sandbox below.

Hint: Each new field sits on its own line in the operation—no commas necessary.

See the solution!

query GetFruitPricesAndNames {
fruits {

Coming up, we'll zoom in from our birds-eye view and focus on the fundamental types in GraphQL, and how we implement them.

Up Next: Introducing Types  

About is maintained by the Apollo team. Our goal is to give developers and technical leaders the tools they need to understand and adopt GraphQL. 2024