Sitemap
shubham

shubham

GraphQL Queries and Mutations: A Deep Dive into Syntax and Examples

5 min readAug 2, 2025

--

GraphQL has revolutionized how we think about API design and data fetching. Unlike traditional REST APIs, GraphQL provides a single endpoint with a powerful query language that allows clients to request exactly the data they need. In this comprehensive guide, we’ll explore the two fundamental operations in GraphQL: Queries and Mutations.

Press enter or click to view image in full size
Modern illustration featuring GraphQL logo and branding with visual representations of query and mutation operations, showing data flow arrows between client and server components, accompanied by code snippet backgrounds in blue and purple gradient colors, designed for a technical blog post about GraphQL queries and mutations.

What is GraphQL?

GraphQL is a query language and runtime for APIs that was developed by Facebook in 2012 and open-sourced in 2015. It 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 APIs easier to evolve over time.

GraphQL Queries: Fetching Data

Queries in GraphQL are used to read or fetch data. They are declarative, allowing you to specify exactly what data you want and how you want it structured.

Basic Query Syntax

The fundamental structure of a GraphQL query follows this pattern:

query {
fieldName {
subField1
subField2
}
}

Simple Query Examples

Example 1: Fetching User Information

query {
user(id: "123") {
id
name
email
age
}
}

Response:

{
"data": {
"user": {
"id": "123",
"name": "John Doe",
"email": "john.doe@example.com",
"age": 30
}
}
}

Example 2: Fetching Multiple Users

query {
users {
id
name
email
posts {
title
content
}
}
}

Named Queries

You can give your queries descriptive names for better organization and debugging:

query GetUserProfile {
user(id: "123") {
id
name
email
profile {
bio
avatar
location
}
}
}

Query Arguments

GraphQL supports various argument types to filter and customize your data requests.

Example 1: Filtering with Arguments

query {
posts(limit: 10, status: PUBLISHED, orderBy: CREATED_AT_DESC) {
id
title
content
author {
name
email
}
createdAt
}
}

Example 2: Pagination Arguments

query {
users(first: 20, after: "cursor123") {
edges {
node {
id
name
email
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}

Variables in Queries

Instead of hardcoding values, you can use variables to make your queries dynamic and reusable.

Get shubham’s stories in your inbox

Join Medium for free to get updates from this writer.

Query with Variables:

query GetUserPosts($userId: ID!, $limit: Int = 10) {
user(id: $userId) {
name
posts(limit: $limit) {
id
title
content
publishedAt
}
}
}

Variables Object:

{
"userId": "123",
"limit": 5
}

Aliases

Aliases allow you to rename the result of a field to anything you want:

query {
currentUser: user(id: "123") {
id
name
}
anotherUser: user(id: "456") {
id
name
}
}

Response:

{
"data": {
"currentUser": {
"id": "123",
"name": "shubham"
},
"anotherUser": {
"id": "456",
"name": "swapnil"
}
}
}

Fragments

Fragments are reusable units that let you construct sets of fields and include them in multiple queries:

fragment UserDetails on User {
id
name
email
profile {
bio
avatar
}
}

query {
user(id: "123") {
...UserDetails
posts {
title
content
}
}
}

Inline Fragments

Inline fragments are useful when querying fields on union types or interfaces:

query {
search(text: "GraphQL") {
... on Article {
title
content
author {
name
}
}
... on Video {
title
duration
thumbnail
}
}
}

Directives in Queries

GraphQL provides built-in directives like @include and @skip for conditional field inclusion:

query GetUser($includeEmail: Boolean!, $skipPosts: Boolean!) {
user(id: "123") {
id
name
email @include(if: $includeEmail)
posts @skip(if: $skipPosts) {
title
content
}
}
}

GraphQL Mutations: Modifying Data

Mutations in GraphQL are used to write or modify data on the server. While queries are used to fetch data, mutations are used for creating, updating, or deleting data.

Basic Mutation Syntax

The fundamental structure of a GraphQL mutation:

mutation {
mutationName(input: { field1: value1, field2: value2 }) {
returnField1
returnField2
}
}

Simple Mutation Examples

Example 1: Creating a User

mutation {
createUser(input: {
name: "Alice Johnson"
email: "alice@example.com"
age: 28
}) {
id
name
email
createdAt
}
}

Response:

{
"data": {
"createUser": {
"id": "456",
"name": "Alice Johnson",
"email": "alice@example.com",
"createdAt": "2025-08-02T14:30:00Z"
}
}
}

Example 2: Updating a User

mutation {
updateUser(id: "123", input: {
name: "John Smith"
email: "john.smith@example.com"
}) {
id
name
email
updatedAt
}
}

Named Mutations

Like queries, mutations can have descriptive names:

mutation CreateNewBlogPost {
createPost(input: {
title: "Getting Started with GraphQL"
content: "GraphQL is a powerful query language..."
authorId: "123"
tags: ["graphql", "api", "tutorial"]
}) {
id
title
slug
author {
name
}
createdAt
}
}

Mutations with Variables

Using variables makes mutations more flexible and secure:

mutation CreateUser($userInput: CreateUserInput!) {
createUser(input: $userInput) {
id
name
email
profile {
bio
}
}
}

Variables Object:

{
"userInput": {
"name": "Bob Wilson",
"email": "bob@example.com",
"profile": {
"bio": "Software developer passionate about GraphQL"
}
}
}

Complex Mutation Examples

Example 1: Creating a Post with Relationships

mutation CreatePostWithTags {
createPost(input: {
title: "Advanced GraphQL Techniques"
content: "In this post, we'll explore..."
authorId: "123"
categoryId: "tech"
tags: ["graphql", "advanced", "techniques"]
publishedAt: "2025-08-02T14:30:00Z"
}) {
id
title
slug
author {
id
name
}
category {
id
name
}
tags {
id
name
}
publishedAt
}
}

Example 2: Batch Operations

mutation BatchUserOperations {
createUser(input: {
name: "User One"
email: "user1@example.com"
}) {
id
name
}

updateUser(id: "456", input: {
name: "Updated User"
}) {
id
name
updatedAt
}

deleteUser(id: "789") {
success
message
}
}

Error Handling in Mutations

GraphQL mutations can return errors alongside data:

mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
... on User {
id
name
email
}
... on ValidationError {
field
message
}
}
}

File Upload Mutations

For file uploads, GraphQL often uses the multipart form specification:

mutation UploadUserAvatar($userId: ID!, $file: Upload!) {
uploadAvatar(userId: $userId, file: $file) {
id
avatarUrl
updatedAt
}
}

Advanced Query and Mutation Features

Subscriptions Integration

While not the focus of this post, queries and mutations often work with subscriptions:

subscription {
postUpdated(id: "123") {
id
title
content
updatedAt
}
}

Custom Scalars

GraphQL supports custom scalar types beyond the built-in ones (String, Int, Float, Boolean, ID):

query {
event(id: "123") {
id
title
startDate # Custom DateTime scalar
location # Custom JSON scalar
attendees # Custom Email scalar array
}
}

Nested Mutations

Some GraphQL implementations support nested mutations for related data:

mutation CreateUserWithProfile {
createUser(input: {
name: "John Doe"
email: "john@example.com"
profile: {
bio: "Software engineer"
location: "New York"
socialLinks: {
twitter: "johndoe"
linkedin: "john-doe"
}
}
}) {
id
name
profile {
bio
location
socialLinks {
twitter
linkedin
}
}
}
}

--

--