Examples

Copy-ready GraphQL patterns for common use cases. Each example includes a query and explanation of when to use it.

Basic Query

Fetch a single resource by ID. The simplest possible query — request specific fields and nothing more.

GraphQL
{
  user(id: "42") {
    id
    name
    email
  }
}

Nested Query

Request related data in a single round-trip. Here, we fetch a user and their recent posts along with each post's comment count.

GraphQL
query UserWithPosts($userId: ID!) {
  user(id: $userId) {
    name
    posts(first: 10) {
      edges {
        node {
          title
          publishedAt
          commentCount
        }
      }
    }
  }
}

Mutation

Create a new resource using an input type. The mutation returns the created object so the client can update its local cache.

GraphQL
mutation CreatePost($input: CreatePostInput!) {
  createPost(input: $input) {
    id
    title
    body
    published
    createdAt
  }
}

# Variables
# {
#   "input": {
#     "title": "Cursor Pagination in Practice",
#     "body": "Cursor-based pagination provides...",
#     "tags": ["graphql", "pagination"],
#     "published": true
#   }
# }

Subscription

Listen for real-time events over WebSocket. The server pushes data to the client whenever the specified event occurs.

GraphQL
subscription OnCommentAdded($postId: ID!) {
  commentAdded(postId: $postId) {
    id
    text
    author {
      name
      avatar
    }
    createdAt
  }
}

Cursor-Based Pagination

The Relay connection specification. Use first/after for forward pagination, last/before for backward. Cursors are opaque strings — treat them as tokens, not offsets.

GraphQL
query PaginatedPosts($first: Int!, $after: String) {
  posts(first: $first, after: $after) {
    edges {
      cursor
      node {
        id
        title
        excerpt
        author { name }
      }
    }
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
    totalCount
  }
}

Filtering

Pass filter arguments to narrow results. Use an input type to group filter parameters. This keeps the schema organized and makes queries readable.

GraphQL
query FilteredPosts($filter: PostFilter) {
  posts(filter: $filter, first: 20) {
    edges {
      node {
        id
        title
        tags
        publishedAt
      }
    }
  }
}

# Variables
# {
#   "filter": {
#     "tags": ["graphql"],
#     "publishedAfter": "2024-01-01",
#     "status": "PUBLISHED"
#   }
# }

Authentication Header

Pass a bearer token in the HTTP headers. The server extracts the token, verifies it, and attaches the authenticated user to the GraphQL context.

HTTP + GraphQL
# Headers
{
  "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6...",
  "Content-Type": "application/json"
}

# Query
query Me {
  me {
    id
    name
    email
    role
    permissions
  }
}

Error Handling

GraphQL responses include partial data alongside errors. The extensions field carries structured error metadata such as codes that clients can handle programmatically.

Response
{
  "data": {
    "updatePost": null
  },
  "errors": [
    {
      "message": "Not authorized to update this post",
      "path": ["updatePost"],
      "extensions": {
        "code": "FORBIDDEN",
        "timestamp": "2025-01-20T14:32:00Z"
      }
    }
  ]
}

Fragments

Reuse field selections across multiple queries. Fragments reduce duplication and keep queries maintainable as the schema grows.

GraphQL
fragment PostFields on Post {
  id
  title
  excerpt
  publishedAt
  author {
    name
  }
}

query Dashboard {
  recentPosts(first: 5) {
    ...PostFields
  }
  popularPosts(first: 5) {
    ...PostFields
    viewCount
  }
}

Aliased Batch Operations

Execute multiple operations of the same type in a single request using aliases. Each alias maps to a separate resolver call.

GraphQL
mutation BatchUpdate {
  first: updatePostStatus(id: "101", status: PUBLISHED) {
    id
    status
  }
  second: updatePostStatus(id: "102", status: PUBLISHED) {
    id
    status
  }
  third: updatePostStatus(id: "103", status: ARCHIVED) {
    id
    status
  }
}