<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 "> What is GraphQL?

What is GraphQL?

Overview

In this section, we will:

  • Review how a standard REST API works, as a baseline
  • Learn what GraphQL is (and what it isn’t)
  • Compare GraphQL to a REST API
  • Weigh the benefits and trade-offs of using GraphQL
  • Run our first query

Objective 1: Understand GraphQL

Starting point: how a REST API works

In a REST API, the server exposes resources, and each resource has its own URL. For our insurance company, that’s something like:

GET    /policies            # list policies
GET    /policies/p1         # one policy
POST   /policies            # create a policy
PATCH  /policies/p1         # update a policy
GET    /policyholders/ph1   # one policyholder

Three properties of that design matter for the comparison:

  • The server decides the response shape. GET /policies/p1 returns whatever fields the endpoint’s author chose to include. The client takes the whole object and ignores what it doesn’t need.
  • One request returns one kind of thing. /policies/p1 returns a policy. If that policy’s owner is represented as "policyholderId": "ph1", getting the owner’s name is a second request to /policyholders/ph1.
  • The URL and the HTTP method carry the meaning. GET reads, POST creates, the path says which resource, and the HTTP status code says what happened: 200 for success, 404 for a missing resource, 500 for a server error.

Here’s a concrete version. Say a screen lists every policy with its policyholder’s name. GET /policies returns:

[
  { "id": "p1", "policyNumber": "AUTO-100001", "type": "AUTO", "monthlyPremium": 142.5,
    "effectiveDate": "2025-01-15", "riskTier": "MEDIUM", "policyholderId": "ph1" },
  { "id": "p2", "policyNumber": "HOME-100002", "type": "HOME", "monthlyPremium": 98,
    "effectiveDate": "2024-06-01", "riskTier": "LOW", "policyholderId": "ph1" }
]

The screen needs two fields per policy: policyNumber and the policyholder’s name. This response has extra fields and no name. So the client sends more requests, one per policyholder, and then stitches the results together itself.

REST is a well-understood design, and most APIs you’ll use are built this way. Its two costs, extra data and extra round trips, come from the properties above. GraphQL addresses both.

What is GraphQL?

GraphQL is a query language for APIs, plus a server runtime that answers those queries using functions you write.

GraphQL is not a database. It sits in front of your data sources: databases, REST APIs, or other services. The API in this course starts with data written into its code, and saves your changes to a JSON file. The same API could read from Postgres instead, without the client ever noticing.

GraphQL was created at Facebook in 2012 and open-sourced in 2015. Since 2019, it has been governed by the GraphQL Foundation, a non-profit hosted by the Linux Foundation.

GraphQL vs REST

Imagine we’re building a screen for an insurance company that lists each policy with the name of its policyholder.

With a REST API, the server decides the shape of each response, and each resource lives at its own URL:

GET /policies           # returns every field of every policy
GET /policyholders/ph1  # then one request per policyholder...
GET /policyholders/ph2
GET /policyholders/ph3

This shows the two classic REST pain points:

  • Over-fetching: /policies returns every field, even the ones the screen doesn’t use.
  • Under-fetching: one call isn’t enough, so the client makes several round trips (or asks the backend team for a new endpoint).

With GraphQL, there is one endpoint, and the client describes exactly what it wants:

{
  policies {
    policyNumber
    policyholder {
      name
    }
  }
}

The response has the same shape as the query.

With REST the client sends four requests: GET /policies, then GET /policyholders/ph1, ph2 and ph3, and every field of every policy comes back. With GraphQL the client sends one request to POST /graphql and gets back exactly the fields it asked for.
The same screen, fetched both ways.

Here are the first two of the five policies:

{
  "data": {
    "policies": [
      { "policyNumber": "AUTO-100001", "policyholder": { "name": "Maria Alvarez" } },
      { "policyNumber": "HOME-100002", "policyholder": { "name": "Maria Alvarez" } }
    ]
  }
}

Why teams choose GraphQL

  • Clients get exactly what they need. A mobile screen and a desktop screen can ask for different fields from the same API.
  • Fewer round trips for related data.
  • A strongly typed schema is the contract. It powers tooling for free: autocomplete, documentation, validation, and code generation.
  • APIs evolve without versioning. New fields can be added at any time, and old ones retired with @deprecated instead of shipping a /v2.
  • One graph over many services. Several teams’ APIs can be combined into a single graph, using federation. Federation has its own training.

Trade-offs

  • Caching is harder. Most clients send every query as a POST to the same URL, and browsers and CDNs don’t cache POST requests. A server can also accept queries as GET requests, which can be cached, but that takes extra setup, like persisted queries. Many teams rely on client-side caches instead.
  • Nested queries can get expensive. A client can ask for policies → policyholder → policies → policyholder… as deep as it likes. Production APIs add depth or complexity limits.
  • More upfront work. You write a schema and resolvers. For a simple CRUD API, that may be overkill.
  • Errors look different. A request the server can’t parse or validate, like one asking for a field that doesn’t exist, gets HTTP 400. But a query that fails while it runs usually still gets HTTP 200, with the problem in an errors array next to data. Code that only checks the HTTP status misses those failures.
  • REST can close part of the gap. A well-designed REST API can let clients request a subset of fields and include related resources in one response. Specs like JSON:API define exactly that, with fields[] and include parameters. If sparse fields and fewer round trips are the only things you want, you may be able to get them without adopting GraphQL.

So when is GraphQL clearly the right call?

A single service with a handful of screens usually doesn’t need GraphQL. The schema and resolvers are real upfront work, and a sparse-fieldset REST API gets you much of the benefit.

GraphQL earns its cost when many services have to look like one API. With several teams each owning part of the data, the alternatives are a hand-written aggregation layer that someone has to maintain, or clients that know every backend’s URL. Federation lets each team own its slice of a single graph, and the client sends one query without knowing how many services answered it.

This course teaches schemas, queries and resolvers on one small service. Federation is built on the same pieces.

Objective 2: Run your first query

You’ll run queries in Apollo Sandbox, which you opened in Course Setup.

Sandbox opens to its Explorer, the page for writing and running operations. If you’ve moved to another page, click Explorer in the left sidebar to get back. You write a query in the Operation panel, click Run, and the result shows in the Response panel.

Exercise

✏️ In Apollo Sandbox, write a query that returns the response below, then click Run. It should have the same fields, in the same shape, and nothing extra. Your response should be:

{
  "data": {
    "policies": [
      { "policyNumber": "AUTO-100001", "type": "AUTO" },
      { "policyNumber": "HOME-100002", "type": "HOME" },
      { "policyNumber": "AUTO-100003", "type": "AUTO" },
      { "policyNumber": "LIFE-100004", "type": "LIFE" },
      { "policyNumber": "RENTERS-100005", "type": "RENTERS" }
    ]
  }
}

Hint: The Documentation panel on the left lists every field you can ask for. For a starting point, look at the query in GraphQL vs REST above; you’ll only need to change which fields it asks for.

Solution

Click to see the solution
{
  policies {
    policyNumber
    type
  }
}

Each field in the query appears in the response, in the same order and nesting.

Next steps

Next, we’ll meet the policyholders and policies in the course API.