GraphQL Overview

Updated 5 interview angles 5 min read source
On this page12
  1. The defining example
  2. What GraphQL is and isn’t
  3. The three operations
  4. When GraphQL fits
  5. When GraphQL doesn’t fit
  6. The architecture
  7. Resolvers — one function per field
  8. The “everything in one endpoint” question
  9. The “always 200” question
  10. Files in this folder
  11. Common interview confusions
  12. Interview angle

GraphQL Overview

GraphQL is a query language for APIs, created by Facebook (2012, open-sourced 2015). Instead of fixed endpoints returning fixed shapes, clients send a query specifying exactly what they want — and the server returns exactly that.

For comparison with REST/gRPC/SOAP see API Protocols Comparison — REST, GraphQL, gRPC, SOAP. This folder is the deep dive.

The defining example

REST — many endpoints, fixed shapes:

http
GET /api/users/42           → user object
GET /api/users/42/posts     → list of posts
GET /api/users/42/followers → list of followers

Three round trips. Each returns more than the screen needs (over-fetching).

GraphQL — one endpoint, client-specified shape:

graphql
query {
  user(id: 42) {
    name
    avatar
    posts(limit: 5) { title, excerpt }
    followers(limit: 10) { name, avatar }
  }
}

One round trip. Server returns exactly the requested fields:

json
{
  "data": {
    "user": {
      "name": "Alice",
      "avatar": "https://...",
      "posts": [{"title": "...", "excerpt": "..."}],
      "followers": [{"name": "...", "avatar": "..."}]
    }
  }
}

What GraphQL is and isn’t

GraphQL is GraphQL isn’t
a query language for APIs a database query language (despite the name)
typed schema a transport (it’s usually HTTP, but the spec is transport-agnostic)
client-driven shape always JSON (binary GraphQL exists; rare)
introspectable “REST replacement” — they solve different problems

GraphQL is HTTP+JSON+a schema+a query language. The transport is mundane (POST to /graphql). The interesting stuff is the schema and resolver model.

The three operations

Operation Purpose
query read data (idempotent, like GET)
mutation write data (POST/PUT/DELETE)
subscription stream data (WebSocket / SSE)
graphql
query GetUser {
  user(id: 42) { name email }
}

mutation CreateUser {
  createUser(input: {name: "Alice", email: "a@b.com"}) {
    id
    createdAt
  }
}

subscription OnNewMessage {
  messageAdded(roomId: "abc") { id, content, author }
}

See Queries, Mutations, Subscriptions.

When GraphQL fits

  • Many clients with different needs — mobile, web, partner integrations all hitting the same data with different field requirements.
  • Heterogeneous screens — one product page needs user+posts+follows; another needs just user+posts.
  • Aggregator UIs — combining multiple backend services into one response, avoiding waterfall round-trips from the client.
  • Rapid frontend iteration — adding new fields doesn’t need a backend deploy if the schema already has them.

When GraphQL doesn’t fit

  • Public-facing APIs with unknown clients — REST’s HTTP caching wins; rate limiting is easier.
  • Simple CRUD — GraphQL’s schema + resolver overhead isn’t justified.
  • Heavy file uploads/downloads — GraphQL multipart is awkward; REST is fine.
  • APIs where each “query” is its own product — Stripe, Twilio, SendGrid all stay REST.

The rule: GraphQL pays off when clients have diverse data needs against the same backend.

The architecture

text
┌──────────────────────┐
│ Client                │  ← sends query string
└──────────────────────┘
          ↓ HTTP POST /graphql
┌──────────────────────┐
│ GraphQL server        │
│  ┌─────────────────┐  │
│  │ Schema (SDL)    │  │  ← types, fields
│  ├─────────────────┤  │
│  │ Query parser    │  │
│  ├─────────────────┤  │
│  │ Validator       │  │  ← against schema
│  ├─────────────────┤  │
│  │ Executor        │  │  ← calls resolvers in order
│  └─────────────────┘  │
│  ┌─────────────────┐  │
│  │ Resolvers       │  │  ← per-field code
│  └─────────────────┘  │
└──────────────────────┘

┌──────────────────────┐
│ Data sources         │  ← DB, REST APIs, gRPC services
└──────────────────────┘

The schema is the contract. The resolvers are the implementation.

Resolvers — one function per field

python
async def resolve_user(parent, info, id):
    return await db.get_user(id)

async def resolve_posts(user, info):
    return await db.get_posts_by_author(user.id)

Each field has a resolver. The executor walks the query tree, calling resolvers as it goes. This is where N+1 happens — one query fetches 100 users, then the posts resolver runs 100 times, each hitting the DB.

The fix: DataLoader (batches and caches resolver calls within a single request). See Resolvers, N+1, and DataLoader.

The “everything in one endpoint” question

GraphQL apps almost always use:

http
POST /graphql
Content-Type: application/json
{"query": "...", "variables": {...}, "operationName": "..."}

Same URL for every request. Implications:

  • HTTP caching doesn’t work (same URL).
  • Rate limiting needs to inspect the query.
  • Per-endpoint metrics don’t apply — instrument resolvers individually.

The “always 200” question

GraphQL returns HTTP 200 for “the server received and processed the query” regardless of whether business logic succeeded.

json
{
  "data": {"user": null},
  "errors": [
    {"message": "User not found", "path": ["user"], "extensions": {"code": "NOT_FOUND"}}
  ]
}

Partial responses are normal: some fields succeed, others fail. The errors array reports failures; data contains whatever succeeded.

Files in this folder

Common interview confusions

  • “GraphQL is a database.” — no. It’s an API query language.
  • “GraphQL replaces REST.” — they solve overlapping but different problems. Many teams use both.
  • “GraphQL eliminates over-fetching.” — under-fetching, yes. Over-fetching at the DB layer can be worse than REST if resolvers are naive.
  • “GraphQL is always faster than REST.” — single-roundtrip wins; per-query CPU often worse. Wash for simple cases; depends on workload.

Interview angle 5

  • “What is GraphQL?” — query language for APIs where the client specifies what fields it wants and the server returns exactly that. Single endpoint, typed schema, three operation types.
  • “Why use GraphQL instead of REST?” — clients with heterogeneous needs, aggregator UIs that combine many sources, rapid frontend iteration without backend deploys. Best when many different frontends hit the same backend.
  • “Why NOT use GraphQL?” — HTTP caching breaks (single URL), rate limiting needs query inspection, simple CRUD doesn’t justify the overhead, public APIs are easier as REST.
  • “What’s a resolver?” — function per field that fetches the value. Server walks the query tree, calling resolvers. Where N+1 problems live — fix with DataLoader.
  • “Why does GraphQL always return HTTP 200?” — distinguishes “server received your query” (200) from “query succeeded fully” (look at errors). Allows partial responses.