GraphQL cheat sheet

A scannable GraphQL reference: 15 short snippets across 8 topics, each linking back to the lesson it came from.

At a glance

TopicWhat it covers
Writing queries: variables, fragments and directivesNamed operations, variables with defaults, fragments on types and interfaces, aliases, and conditional inclusion withlesson
Pagination and the connection patternReturning a bare list without a limit is the most common GraphQL production incident: one client asks for everythinglesson
Error handling, validation and custom scalarsValidate before touching the database, and validate again in the data layer. Schema validation proves the shape; itlesson
DataLoader and solving the N+1 problemThe resolver has no way to know it is one of fifty. DataLoader solves it by deferring resolution to the end of thelesson
Subscriptions and real-time updatesTreat a subscription as an optimisation, never as the only source of truth. The client should be able to reconstructlesson
Schema design, evolution and toolingGenerate types from the deployed schema, not from a copy in the repository, or the drift you were trying to preventlesson
Testing GraphQL APIsResolver unit tests, integration tests that execute a real document, schema snapshots, mocking data sources and testinglesson
Federation, caching and next stepsEvery request is a POST to one URL, so CDNs and browsers cannot use the URL as a cache key. Caching has to move to twolesson

Quick snippets

Writing queries: variables, fragments and directives

Variables instead of string building

{
  "authorId": "42",
  "first": 5,
  "includeReviews": true
}

Full lesson: Writing queries: variables, fragments and directives →

Pagination and the connection pattern

The connection shape

query Page($first: Int!, $after: String) {
  books(first: $first, after: $after) {
    nodes { id title }
    pageInfo { hasNextPage endCursor }
  }
}

Full lesson: Pagination and the connection pattern →

Error handling, validation and custom scalars

A model clients can code against

{
  "data": {
    "placeOrder": {
      "order": null,
      "errors": [
        { "field": "couponCode", "code": "COUPON_EXPIRED", "message": "This coupon expired on 1 June." }
      ]
    }
  }
}

Input validation

input CreateBookInput {
  title: String!
  isbn: String!
  pageCount: Int!
  publishedOn: Date
}

scalar Date
scalar DateTime
scalar URL

Full lesson: Error handling, validation and custom scalars →

DataLoader and solving the N+1 problem

The shape of the problem

query {
  books(first: 50) {
    nodes {
      id
      title
      author { name }
    }
  }
}

The shape of the problem

-- 1 query for the list
select * from book order by created_at desc limit 50;

-- then 50 more, because Book.author resolves once per node
select * from author where id = 1;
select * from author where id = 1;
select * from author where id = 7;
-- ... 48 more

Creating and using loaders

Mutation: {
  async updateAuthor(_p, { id, name }, ctx) {
    const updated = await ctx.db.author.update({ where: { id }, data: { name } });
    ctx.loaders.authorById.clear(id);      // otherwise the stale value is served
    return updated;
  },
}

Full lesson: DataLoader and solving the N+1 problem →

Subscriptions and real-time updates

Defining a subscription

type Subscription {
  bookPublished(authorId: ID!): Book!
  orderStatusChanged(orderId: ID!): OrderStatusEvent!
}

type OrderStatusEvent {
  orderId: ID!
  status: OrderStatus!
  changedAt: DateTime!
}

Delivery and reliability

import { RedisPubSub } from "graphql-redis-subscriptions";
import Redis from "ioredis";

const pubsub = new RedisPubSub({
  publisher: new Redis(process.env.REDIS_URL),
  subscriber: new Redis(process.env.REDIS_URL),
});

// a client that reconnects must catch up
// query the delta since lastEventId before resuming the subscription
const { data } = await client.query({ query: ORDER_EVENTS_SINCE, variables: { since: lastEventId } });

Running subscriptions in production

// a graceful shutdown that closes sockets properly
process.on("SIGTERM", async () => {
  await server.stop();          // stop accepting new connections
  await pubsub.close();         // release the redis subscribers
  await db.destroy();
  process.exit(0);
});

Full lesson: Subscriptions and real-time updates →

Schema design, evolution and tooling

Changing a schema without breaking clients

type Book {
  id: ID!
  title: String!
  publishedOn: Date @deprecated(reason: "Use publishedAt, which includes a timezone.")
  publishedAt: DateTime
}

type Query {
  books(first: Int): BookConnection!
  allBooks: [Book!]! @deprecated(reason: "Unbounded. Use books with pagination.")
}

Code generation and CI checks

# codegen.yml
schema: http://localhost:4000/graphql
documents: "src/**/*.graphql"
generates:
  src/generated/types.ts:
    plugins:
      - typescript
      - typescript-operations
      - typescript-react-apollo

Code generation and CI checks

# in CI: fail the build on a breaking change
npx graphql-inspector diff origin/main:schema.graphql schema.graphql --rule suppressRemovalOfDeprecatedField
npx graphql-inspector validate "src/**/*.graphql" schema.graphql
npx eslint src --ext .ts

Full lesson: Schema design, evolution and tooling →

Testing GraphQL APIs

Schema snapshots and mocking

import { printSchema, lexicographicSortSchema } from "graphql";

it("matches the published schema", () => {
  const current = printSchema(lexicographicSortSchema(schema));
  expect(current).toMatchSnapshot();
});

// mock a data source so resolver tests stay fast and deterministic
const fakeBookRepo = {
  findPage: vi.fn().mockResolvedValue({ nodes: [{ id: "1", title: "A", authorId: "42" }] }),
  findManyByIds: vi.fn().mockResolvedValue([{ id: "42", name: "Le Guin" }]),
};

Full lesson: Testing GraphQL APIs →

Federation, caching and next steps

Where to go next

query Dashboard {
  summary { orderCount revenue }
  ... @defer {
    recentOrders { nodes { id total } }
  }
}

Full lesson: Federation, caching and next steps →

FAQ

Is this GraphQL cheat sheet free to use?
Yes. No sign-up and no tracking: the page is static, every example is on the page itself, and you can print it or save it as a one-page reference.
Where do the examples come from?
Every snippet is taken from the 8 lessons of the GraphQL course on this site, and each section links back to the lesson it was pulled from.
How do I go deeper than a cheat sheet?
Open the full GraphQL course — it carries the worked explanations, the edge cases and the exercises behind every line here.

Node.js PHP Java HTTP Go Rust

Last refreshed 2026-09-27.