Skip to main content
GraphQL Fundamentals·Lesson 2 of 5

Queries & Mutations

Writing Queries

A query starts with the query keyword (optional for read operations) and specifies exactly which fields to return:

query GetPost($id: ID!) {
  post(id: $id) {
    id
    title
    publishedAt
    author {
      name
      email
    }
    tags
  }
}

Variables are passed separately as JSON — never concatenated into the query string:

{ "id": "post_42" }

Aliases

Fetch the same field twice with different arguments using aliases:

query ComparePosts {
  firstPost:  post(id: "1") { title publishedAt }
  secondPost: post(id: "2") { title publishedAt }
}

The response uses the alias names as keys.

Fragments

Reuse field selections with fragments:

fragment PostFields on Post {
  id
  title
  publishedAt
}

query {
  featuredPost { ...PostFields author { name } }
  latestPost   { ...PostFields }
}

Mutations

Mutations follow the same syntax but use the mutation keyword:

mutation CreatePost($input: CreatePostInput!) {
  createPost(input: $input) {
    id
    title
    publishedAt
  }
}

Variables:

{
  "input": {
    "title": "My First Post",
    "body": "Hello, GraphQL!",
    "authorId": "user_1"
  }
}

Common mutation patterns:

# Update
mutation UpdatePost($id: ID!, $title: String!) {
  updatePost(id: $id, title: $title) { id title }
}

# Delete
mutation DeletePost($id: ID!) {
  deletePost(id: $id)   # returns Boolean or deleted object
}

Query in JavaScript

Ctrl+Enter
HTML
CSS
JS
Preview

Input Types

For mutations with many arguments, group them into an input type:

input CreatePostInput {
  title:    String!
  body:     String!
  authorId: ID!
  tags:     [String!]
}

type Mutation {
  createPost(input: CreatePostInput!): Post!
}

This keeps mutations clean and makes them easier to extend.

Error Handling

GraphQL always returns HTTP 200. Errors go inside the response body:

{
  "data": { "post": null },
  "errors": [
    {
      "message": "Post not found",
      "locations": [{ "line": 2, "column": 3 }],
      "path": ["post"]
    }
  ]
}

Always check for errors in your response, even on a 200 status.