GraphQL Queries and Mutations: A Deep Dive into Syntax and Examples
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.
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
}
}
}
}







