close icon
daily.dev platform

Discover more from daily.dev

Personalized news feed, dev communities and search, much better than what’s out there. Maybe ;)

Start reading - Free forever
Continue reading >

GraphQL Queries & Mutations: A Guide

GraphQL Queries & Mutations: A Guide
Author
Nimrod Kramer
Related tags on daily.dev
toc
Table of contents
arrow-down

🎯

Learn how to effectively use GraphQL queries and mutations. This guide covers key concepts, examples, best practices, and tips for successful GraphQL mutations.

Understanding how to change or update data on a server using GraphQL is crucial for developers. This guide simplifies the process, focusing on two key operations: Queries and Mutations. Here's what you need to know:

  • Mutations allow you to add, update, or delete data.
  • Queries fetch data without altering it.

Key Concepts Covered:

  • Basic mutation structure and examples for creating, updating, and deleting data.
  • The importance of using variables for dynamic data manipulation.
  • Strategies for returning data post-mutation to immediately see changes.
  • Advanced techniques like nested and bulk mutations for efficient data handling.
  • Best practices for ensuring your GraphQL mutations are effective and reliable.

Whether you're adding new users, updating tasks, or managing bulk data changes, this guide provides the foundational knowledge and examples needed to work effectively with GraphQL mutations.

GraphQL Mutation Examples

Create Mutation

Here's a simple way to add a new user:

mutation {
  createUser(input: {name: "John Doe", email: "john@example.com"}) {
    id
  }
}

In this createUser example, you tell it the new user's name and email. After adding the user, it gives you back the user's automatically created id.

Update Mutation

And if you need to update a user's info, you might do something like this:

mutation {
  updateUser(input: {id: "1", email: "john@newdomain.com"}) {
    id 
    name
    email
  }
}

This updateUser example shows how to change a user's email by using their id. You get back the id, name, and the new email.

Delete Mutation

To remove a user, you could use this:

mutation {
  deleteUser(input: {id: "1"}) {
    success
  } 
}

This deleteUser example needs the user's id you want to remove. It tells you if the removal was successful with a simple true or false success flag.

Passing Arguments with Variables

When you use variables in your GraphQL mutations, you make it possible to change the inputs easily. This has a few big benefits:

Reusability

With variables, you can use the same mutation for different things by changing the inputs. For instance:

mutation($text: String!) {
  createTodo(text: $text) {
    id
  }
}

With this setup, you can make many todos just by swapping out the $text value each time.

Decoupling

Variables allow you to keep your mutation code separate from where you're getting your inputs. This means inputs can come from anywhere - like something a user types in or data from another service - without needing to tweak your mutation.

Readability

Putting changeable values into variables makes your mutations easier to understand and keep up with. The main part of your mutation stays the same, and only the variable parts change.

Type Safety

You can specify what type each variable should be, like $text: String!. This makes sure you're always using the right kind of data.

Here's how you might change a todo using variables:

mutation updateTodo($id: ID!, $text: String, $done: Boolean) {
  updateTodo(id: $id, text: $text, done: $done) {
    text
    done 
  }
}

Using variables this way makes your mutations flexible and safe to use over and over. It's a smart way to keep your GraphQL code clean and easy to manage.

Returning Data in Mutations

It's a good idea to get back the updated information right away when you make changes with GraphQL mutations. This way, you don't have to ask again to see what's changed.

Here are a few examples of how you can get back data after you've made some changes:

Update User Mutation

mutation {
  updateUser(input: {id: "1", name: "Jane Doe"}) {
    id
    name 
  }
}

In this example, we change the name of a user with the id "1". After the change, we get back the user's id and their new name.

Create Todo Mutation

mutation {
  createTodo(text:"New todo item") {
    id
    text
    createdAt
  }  
}

This example shows how to add a new task. After adding it, we get back the task's id, what the task is, and when it was created.

Delete Post Mutation

mutation {
  deletePost(id: "123") {
    id
    title
  }
}

Even though this example is about deleting a post, we still get back the post's id and title. This helps update what we know without having to ask for more information.

Getting back updated info right after making changes helps keep things simple. You don't need to know exactly how to get the updated info; you just get it. This makes things easier and avoids extra steps.

Other good things about this include:

  • Better error handling - if something goes wrong, you still know what was there before
  • Optimistic updates - you can guess and update your info before the change is even done
  • Increased performance - you don't waste time asking for info you just changed

So, getting back updated info after making changes is a smart way to keep your GraphQL APIs working smoothly and efficiently.

sbb-itb-bfaad5b

Nested & Bulk Mutations

Nested Mutations

Nested mutations help you do more in one go, especially when you're dealing with items that are connected, like a user and their blog posts.

Imagine you want to add a new user and immediately give them two posts. Here's a simple way to do it all at once:

mutation {
  createUser(data: {
    name: "John",
    posts: {
      create: [
        {title: "My first post"},
        {title: "Another post"}
      ]
    }
  }) {
    id
    name
    posts {
      id
      title 
    }
  }
}

In this example, we:

  • Add a new user named "John"
  • Create two posts for John
  • Get back John's user id, name, and the posts

This way, you save time by making related changes with just one request.

Bulk Mutations

Bulk mutations are about changing lots of items at once based on certain rules.

Let's say you want to make all posts with "GraphQL" in the title published. You can do it like this:

mutation {
  updateManyPosts(
    where: {title_contains: "GraphQL"}
    data: {published: true}
  ) {
    count
  }
}

With this command, you:

  • Look for all posts mentioning "GraphQL"
  • Update them to be published
  • Find out how many posts you changed

This method is super efficient because it handles many updates in one action instead of doing them one by one.

Both nested and bulk mutations are great for:

  • Cutting down on the number of times you need to send requests
  • Keeping your code simple
  • Managing many changes in a single, combined action

Best Practices

Here's how to make sure your GraphQL mutations work well and keep your app running smoothly:

Validate Inputs

Before you let data through, check it carefully. This helps stop bad data from causing problems. Here's how:

  • Make sure you have all the needed info, like an email for signing up.
  • Check that the data looks right, such as making sure IDs are actually IDs.
  • Consider using tools like Joi to set rules on what data should look like.

Modularize Mutation Code

Keep your mutation code neat by breaking it into smaller pieces. This makes it:

  • Readable - Easier to get what's going on
  • Reusable - Lets you use the same bits of code in different places
  • Maintainable - Simpler to update parts without messing up everything

Handle Errors

Things can go wrong, so be ready to deal with mistakes in a smart way:

  • Give clear error messages that users can understand
  • Keep detailed error logs on the server for your own use
  • Make sure you can handle common issues like double entries or wrong data

Write Tests

Tests help you spot problems early and keep your mutations working as expected:

  • Do unit tests on the bits of mutation logic
  • Run integration tests to check the whole process from start to finish
  • Aim to cover more of your code with tests, especially the important parts

Monitor Performance

Use tools to watch how your mutations are doing and look out for:

  • Mutations that get slow when lots of people use your app
  • A rise in errors
  • More requests failing than usual

Keeping an eye on these things means you can make your mutations better when needed.

By sticking to these tips, you'll build mutations that are strong and reliable, making your app better for everyone.

Conclusion

GraphQL mutations are a way to change data on a server. We've talked about important stuff you need to know when using mutations:

Syntax and Structure

  • Start with the word mutation
  • Name it something that makes sense for the change you're making
  • Tell it exactly what to change by giving specific info
  • Ask for updated info back so you know the change worked

Examples

  • How to add, change, or remove things like users or tasks
  • Use details like IDs or specific fields to make changes

Variables

  • Use variables so you can easily change the data you're working with
  • Keep your mutation setup separate from where your data comes from
  • This makes things clearer, easier to use again, and ensures you're working with the right type of data

Returning Data

  • Get the latest info right after making changes
  • This helps you update things faster and deal with mistakes better
  • It also makes your app run smoother and quicker

Nested & Bulk

  • Do a bunch of changes at once with a single request
  • Change many records together to save time and keep things simple

Best Practices

  • Always check your data before sending it through
  • Keep your mutation setups tidy by breaking them into smaller parts
  • Be ready for when things go wrong and know how to fix them
  • Test your setups to catch issues early
  • Keep an eye on how well your mutations are doing

By getting the hang of mutations, you can change data in really effective ways. Understanding these examples, how to set things up, use variables, and follow best practices will help you make your apps better.

What is the difference between a query and a mutation in GraphQL?

When you use GraphQL, queries are for getting data without changing anything. Think of them like asking for information. On the other hand, mutations are for when you want to add, change, or delete data - basically, any action that modifies data.

In short:

  • Queries - They fetch data (READ)
  • Mutations - They change data (WRITE)

This is somewhat like comparing GET to POST/PUT/DELETE in traditional REST APIs.

What are the best practices for GraphQL mutations?

For making good mutations in GraphQL, you should:

  • Start names with a verb like createUser or updatePost
  • Be clear about what each mutation does
  • Organize inputs using input types
  • Give back updated data so you know what changed
  • Group related changes together
  • Check data before making changes
  • Clearly handle any mistakes so users know what went wrong

These tips help make your mutations work better and easier to manage.

How do you implement mutations in GraphQL?

To set up mutations, you:

  • Define what the mutations look like in your schema
  • Write functions (resolvers) that do what the mutations describe
  • Use these mutations from your app or website

For instance:

type Mutation {
  createUser(input: CreateUserInput!): User!
}

input CreateUserInput {
  name: String!
  email: String!
}

type User {
  id: ID!
  name: String!
  email: String!
}

Server-side:

Mutation: {
  createUser: (parent, args) => {
    // Logic to create a user
  }
}

And in your app:

mutation {
  createUser(input: {name:"John", email:"john@example.com"}) {
    id
    name
  }
}

This means you specify your mutation, how it works, and then call it in your app.

What is the GQL function?

The gql function is used in GraphQL tools like Apollo to prepare your queries and mutations. It turns your text into a format that GraphQL understands.

Example:

import { gql } from '@apollo/client';

const GET_USERS = gql`
  query GetUsers {
    users {
      id 
      name
    }
  }
`;

This way, gql helps your app talk to a GraphQL server by formatting your requests correctly.

Related posts

Why not level up your reading with

Stay up-to-date with the latest developer news every time you open a new tab.

Read more