TechLead
Lesson 1 of 20
5 min read
GraphQL

GraphQL Fundamentals

Understand what GraphQL is, its core principles, and why it has become the modern standard for API development

What is GraphQL?

GraphQL is a query language for APIs and a runtime for executing those queries against your data. Developed internally by Facebook in 2012 and open-sourced in 2015, GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need, and makes it easier to evolve APIs over time.

Unlike REST, where the server determines what data is returned for each endpoint, GraphQL shifts that power to the client. The client sends a query describing the exact shape of data it needs, and the server responds with precisely that shape — nothing more, nothing less.

Core Principles of GraphQL

  • Declarative Data Fetching: Clients specify what data they need in a single query, not which endpoints to hit
  • Strongly Typed Schema: Every GraphQL API is defined by a schema using the GraphQL Schema Definition Language (SDL)
  • Single Endpoint: All interactions happen through one endpoint, unlike REST which uses many
  • Hierarchical: Queries mirror the shape of the data they return, making them intuitive to write and read
  • Introspective: Clients can query the schema itself to discover available types, fields, and operations

A Simple GraphQL Query

Here is a basic example that demonstrates the elegance of GraphQL. The client asks for specific fields on a user, and the server returns exactly those fields:

# Client query — ask for exactly what you need
query {
  user(id: "1") {
    name
    email
    posts {
      title
      publishedAt
    }
  }
}

The server responds with data that matches the query shape exactly:

{
  "data": {
    "user": {
      "name": "Alice Johnson",
      "email": "alice@example.com",
      "posts": [
        {
          "title": "Getting Started with GraphQL",
          "publishedAt": "2025-03-15"
        },
        {
          "title": "Advanced Schema Design",
          "publishedAt": "2025-04-01"
        }
      ]
    }
  }
}

The Three GraphQL Operations

GraphQL supports three types of operations, each serving a distinct purpose in client-server communication:

Operation Types

Operation Purpose REST Equivalent
QueryRead dataGET
MutationWrite / modify dataPOST, PUT, PATCH, DELETE
SubscriptionReal-time updates via WebSocketWebSocket / SSE

GraphQL Schema Definition Language (SDL)

The schema is the contract between client and server. It defines all the types, fields, and relationships available in your API. SDL is a human-readable syntax for defining schemas:

type User {
  id: ID!
  name: String!
  email: String!
  age: Int
  posts: [Post!]!
  role: Role!
}

type Post {
  id: ID!
  title: String!
  body: String!
  author: User!
  comments: [Comment!]!
  publishedAt: String
}

type Comment {
  id: ID!
  text: String!
  author: User!
}

enum Role {
  ADMIN
  EDITOR
  VIEWER
}

type Query {
  user(id: ID!): User
  users: [User!]!
  post(id: ID!): Post
  posts(limit: Int, offset: Int): [Post!]!
}

type Mutation {
  createUser(name: String!, email: String!, role: Role!): User!
  createPost(title: String!, body: String!, authorId: ID!): Post!
  deletePost(id: ID!): Boolean!
}

Understanding SDL Syntax

  • Scalar types: String, Int, Float, Boolean, ID are built-in scalars
  • Non-null (!): A trailing ! means the field can never be null — String! guarantees a string value
  • Lists ([]): [Post!]! means a non-null list of non-null Post items
  • Enums: Define a fixed set of allowed values like Role
  • Arguments: Fields can accept arguments like user(id: ID!)

How GraphQL Execution Works

When a GraphQL server receives a query, it goes through several phases to produce the response:

  1. Parsing: The query string is parsed into an Abstract Syntax Tree (AST). Syntax errors are caught at this stage.
  2. Validation: The AST is validated against the schema. The server checks that all requested fields exist, argument types match, and required arguments are provided.
  3. Execution: The server walks the AST and calls a resolver function for each field. Resolvers fetch data from databases, other APIs, or any data source.
  4. Response: The resolved data is assembled into a JSON response matching the query shape and returned to the client.
// Simplified execution flow in TypeScript
import { graphql, buildSchema } from 'graphql';

const schema = buildSchema(`
  type Query {
    hello: String
    user(id: ID!): User
  }

  type User {
    id: ID!
    name: String!
    email: String!
  }
`);

const rootValue = {
  hello: () => 'Hello, GraphQL!',
  user: ({ id }: { id: string }) => {
    // In real apps, fetch from database
    return { id, name: 'Alice', email: 'alice@example.com' };
  },
};

// Execute a query
const result = await graphql({
  schema,
  source: '{ hello, user(id: "1") { name email } }',
  rootValue,
});

console.log(result);
// { data: { hello: "Hello, GraphQL!", user: { name: "Alice", email: "alice@example.com" } } }

GraphQL Ecosystem Overview

The GraphQL ecosystem has matured significantly. Here are the most important tools and libraries you will encounter:

Key Tools and Libraries

Category Tool Description
ServerApollo ServerProduction-ready GraphQL server for Node.js
ClientApollo ClientFull-featured caching GraphQL client for React
ClienturqlLightweight, extensible GraphQL client
Code GenGraphQL Code GeneratorGenerates TypeScript types from your schema
IDEGraphiQL / Apollo StudioIn-browser IDE for exploring GraphQL APIs
FederationApollo FederationArchitecture for composing multiple GraphQL services

When to Use GraphQL

GraphQL is not a universal replacement for REST. It excels in certain scenarios and may be overkill in others. Understanding when to reach for GraphQL is crucial:

  • Complex data requirements: When clients need to fetch related data from multiple resources in a single request
  • Multiple client platforms: When mobile, web, and desktop apps need different data shapes from the same API
  • Rapid iteration: When your frontend evolves quickly and you want to avoid waiting for backend endpoint changes
  • Real-time features: When your app needs subscriptions for live updates
  • Microservices: When you need a unified API layer in front of multiple backend services

Key Takeaways

  • GraphQL is a query language and runtime — not a database or storage engine
  • Clients drive data requirements — they ask for exactly the fields they need
  • Strongly typed schemas — provide contracts, documentation, and tooling automatically
  • Single endpoint architecture — simplifies API versioning and reduces over-fetching
  • Rich ecosystem — Apollo, Relay, urql, and many other mature tools support production use

Continue Learning