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 →
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.
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.
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.
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.
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.
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.
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.
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.
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 {price}}
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.
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 {pricename}}
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
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