GraphQL comes up when teams talk about new apps, headless shops and "the front end being blocked on the back end". It's a different way of asking an API for data, and it changes who decides what comes back. You don't need to write a query to be good at your job, but knowing what GraphQL is, and what it costs, helps you follow those conversations and ask the right questions.
This series follows on from APIs for product managers, which explains APIs from the beginning with a live weather page. If words like request, response, JSON and status code are new, start there. This series has a live example too: a country explorer on this site that asks a free GraphQL API for facts about a country.
The short version
GraphQL is a way of asking an API for data. With most APIs (the REST kind, which the APIs series uses), there's a web address for each thing and each address sends back a fixed answer. With GraphQL, there's one address, and your product sends a list of exactly the fields it wants. The answer comes back in exactly that shape, with nothing extra.
The "QL" stands for query language, like the SQL used for databases. Facebook built it for its mobile apps in 2012 and shared it publicly in 2015. It's now looked after by an independent foundation and used by companies of every size.
Set menu or your own order
In the APIs series, an API was a waiter taking your order to a kitchen you never see. REST and GraphQL are two ways of ordering. Take the card on the country explorer: a country's name, capital, languages and continent. Switch between the two to see how each gets it:
The same card, two ways
LikeOrdering from a set menu: each dish comes the way the kitchen plates it, sides and all, and anything from the dessert menu is another order
REST. An address for each thing. The card needs a country, its languages and its continent, so that's three requests, each answered in full.
- 1Your product asks API
GET /countries/GBEvery field the country has - 2Your product asks API
GET /countries/GB/languagesEach language, in full - 3Your product asks API
GET /continents/europeEurope, and every country in it
3 requests one after another, and most of each answer thrown away
LikeWriting your own order on one slip, "the steak, no chips, and the cheesecake", and getting it all on one tray
GraphQL. One address. Your product sends a list of exactly the fields the card shows, and gets back exactly those.
- 1Your product asks API
POST /graphqlwith the name, capital, languages and continent of GB
1 request with nothing wasted
The problems it solves
The REST version above has two problems, and they have names you'll hear in planning:
Two problems GraphQL was built to solve
LikeAsking what time it is and being handed the whole timetable
The answer has far more than you need. On a phone with a weak signal, every unused field is time the customer spends waiting.
LikeHaving to ring three departments to sort out one problem
One answer isn't enough, so the screen has to ask again, and often wait for the first answer before it knows what to ask next.
Neither matters much on a fast laptop. Both matter a lot on a phone on a train, where every trip and every unused byte is time the customer spends looking at a spinner.
The question is the shape of the answer
The neatest thing about GraphQL is that the answer mirrors the question. You can read a query and know what's coming back before you send it:
The question is the shape of the answer
{
country(code: "JP") {
name
capital
languages {
name
}
}
}{
"data": {
"country": {
"name": "Japan",
"capital": "Tokyo",
"languages": [
{ "name": "Japanese" }
]
}
}
}currency to the query and "currency": "JPY" appears in the answer. Take capital out and it disappears.That's useful well beyond developers. A query is a precise, readable list of the data a screen uses, which makes it a handy thing to attach to a ticket or a design.
The schema is the menu
In the APIs series, the menu was the API's documentation. GraphQL makes the menu part of the API itself: a schema that lists every type of thing, every field and what kind of value each one holds.
The schema is the menu
type Country {
code: ID!
name: String!
capital: String
currency: String
languages: [Language!]!
continent: Continent!
}- A country has a name, and it's text (a
String). - The
!means "always there". Every country has a name. - No
!means it can be empty (null). Not every country lists a capital, so the design needs a plan for that. - Square brackets mean a list: a country can have several languages.
LanguageandContinentare types of their own, with their own fields to choose from.
Where you'll meet GraphQL
Where you'll meet GraphQL
Shopify's Storefront API is GraphQL, so a custom shop front asks for exactly the product details each page shows.
Headless content systems such as Contentful offer GraphQL, so a page can fetch an article, its author and related posts in one go.
GitHub has a GraphQL API alongside its REST one, for pulling repositories, issues and people together.
Where it started: apps on slow connections that need lots of related data on one screen.
Big companies often put one GraphQL layer in front of many internal services, so app teams have one place to ask.
Free public APIs like the Countries API in this series, which is a good place to practise.
Phrases you'll hear, translated
- "We'll write a query for that." The data is already available. The screen just needs to ask for it.
- "It's not in the schema." The API doesn't offer that field yet, so it's back-end work first.
- "That's over-fetching." We're downloading data the screen never uses.
- "It's one round trip." Everything for the screen arrives in a single request.
- "Is that field nullable?" Can it come back empty? If so, what should the design show?
Next, Part 2 takes a query apart, lets you send one to a real GraphQL API and looks at what happens when something goes wrong.
