📡 You're offline — showing cached content
New version available!
Quick Access
GraphQL Reference

GraphQL

Queries, mutations, subscriptions, resolvers, and schema design.

All Topics

Queries

query { field }
Basic read operation. Unlike REST, you specify exactly which fields you want — no over-fetching.
Example: query { user(id: "1") { name email posts { title } } }
query Name($var: Type!)
Named query with a required variable. ! means non-nullable. Variables prevent injection attacks.
Example: query GetUser($id: ID!) { user(id: $id) { name } }
aliases
Rename a field in the response — allows requesting the same field twice with different args.
Example: { adult: users(age: 18) { name } child: users(age: 5) { name } }
fragment on Type
Reusable set of fields. Reduces duplication in queries. Spread with ...FragmentName.
Example: fragment UserFields on User { id name email }
@include(if: $bool)
Conditionally include/skip a field based on a boolean variable (client-controlled).
Example: { user { name email @include(if: $showEmail) } }
__typename
Meta-field — returns the type name of any object. Useful for union type resolution on client.
Example: { search { __typename ... on Post { title } ... on User { name } } }

Mutations

mutation { action(input) }
Write operation (create, update, delete). Mutations run sequentially, not in parallel.
Example: mutation { createPost(title: "Hi") { id title } }
input type
Special object type used exclusively as mutation arguments — keeps schema clean and typed.
Example: input CreatePostInput { title: String! body: String }
Optimistic UI pattern
Update local cache immediately before server confirms — makes UI feel instant.
Example: optimisticResponse: { createPost: { id: 'temp', __typename: 'Post' } }
Returning affected fields
Always return the mutated object so clients can update their cache without a refetch.
Example: mutation { updateUser(id:1, name:"A") { id name updatedAt } }
Error payload pattern
Return errors in the payload (not HTTP 400) for predictable client-side error handling.
Example: type MutationResult { success: Boolean! errors: [Error!] }
File uploads (multipart)
Use the graphql-multipart-request-spec with scalar Upload type for file uploads.
Example: mutation($file: Upload!) { uploadAvatar(file: $file) { url } }

Subscriptions & Real-time

subscription { event }
Long-lived connection (WebSocket) — server pushes updates when subscribed events occur.
Example: subscription { messageAdded(chatId: "1") { id body author { name } } }
PubSub engine
Backend event bus that connects resolvers to subscription clients (Redis Pub/Sub for scale).
Example: pubsub.publish('MESSAGE_ADDED', { messageAdded: newMsg })
withFilter()
Filter subscription events per-client — only deliver events the subscriber cares about.
Example: withFilter(asyncIter, (payload, vars) => payload.roomId === vars.roomId)
@defer / @stream
Progressive loading directives — stream parts of a query response as they become ready.
Example: { user { name ... @defer { longComputedField } } }

Schema Design

type / scalar / enum
Object type defines shape / Scalar is a leaf value / Enum is a set of allowed values.
Example: enum Role { ADMIN EDITOR MEMBER }
interface / union
Interface: shared fields across types. Union: one of multiple types (no shared fields needed).
Example: union SearchResult = Post | User | Tag
Relay Cursor Connections
Standardized pagination spec: edges, node, cursor, pageInfo with hasNextPage.
Example: { posts(first: 10, after: "cursor") { edges { node { title } } pageInfo { hasNextPage } } }
Custom Directives
Schema-level annotations for auth, formatting, or caching logic applied to any field.
Example: directive @auth(role: Role) on FIELD_DEFINITION
Schema Stitching / Federation
Combine multiple GraphQL services into one supergraph (Apollo Federation pattern).
Example: @key(fields: "id") type User @extends { id: ID! @external }
DataLoader (N+1 fix)
Batch and cache resolver DB calls — eliminates the N+1 query problem automatically.
Example: const loader = new DataLoader(ids => User.findByIds(ids))

Resolvers & Security

resolver(parent, args, ctx, info)
Four resolver arguments: parent object, field args, shared context, and field AST info.
Example: user: (_, { id }, { db }) => db.users.findById(id)
Context object (ctx)
Shared across all resolvers per request — use it for auth user, DB connection, DataLoader.
Example: context: ({ req }) => ({ user: getUser(req.headers.authorization) })
Query depth limiting
Prevent deeply nested queries from DoS-ing your server — set max depth (usually 5-10).
Example: depthLimit(7) // graphql-depth-limit package
Query complexity scoring
Assign cost to fields and reject queries exceeding a total complexity budget.
Example: createComplexityRule({ maximumComplexity: 1000 })
Persisted Queries
Store query hashes on server — clients send hash instead of full query string (faster + secure).
Example: GET /graphql?extensions={"persistedQuery":{"sha256Hash":"abc"}}
Disable Introspection (prod)
Disable __schema queries in production to hide your API schema from attackers.
Example: introspection: process.env.NODE_ENV !== 'production'