Creating and Using Mutations in GraphQL

Tutorial 2 of 5

1. Introduction

In this tutorial, we will guide you through the process of creating and using mutations in GraphQL. Mutations in GraphQL are a way to change data on the server, similar to POST, PUT, PATCH, or DELETE methods in RESTful services.

You will learn how to:
- Define mutations in your GraphQL schema
- Invoke these mutations in your application

Prerequisites:
- Basic understanding of GraphQL and JavaScript
- Node.js installed on your machine
- A text editor, such as Visual Studio Code

2. Step-by-Step Guide

What are Mutations?

In GraphQL, we use queries to fetch data and mutations to modify data. Mutations are defined on the server-side and called from the client-side.

Creating Mutations

A mutation is defined similarly to a query in your GraphQL schema. Here is an example of a mutation for adding a new book:

type Mutation {
  addBook(title: String, author: String): Book
}

In the above example, addBook is the mutation name, title and author are arguments, and Book is the return type.

Invoking Mutations

To invoke a mutation, you need to use the mutation keyword in your GraphQL request. Here is an example:

mutation {
  addBook(title: "New Book", author: "New Author") {
    title
    author
  }
}

3. Code Examples

Let's create a simple Node.js server using express-graphql and define a mutation for adding a book.

Server Side

const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');

// Construct a schema, using GraphQL schema language
const schema = buildSchema(`
  type Book {
    title: String
    author: String
  }

  type Query {
    books: [Book]
  }

  type Mutation {
    addBook(title: String!, author: String!): Book
  }
`);

let books = [];

// The root provides a resolver for each API endpoint
const root = {
  books: () => books,
  addBook: ({ title, author }) => {
    const book = { title, author };
    books.push(book);
    return book;
  },
};

const app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));

app.listen(4000);
console.log('Running a GraphQL API server at http://localhost:4000/graphql');

Client Side

Here’s how you can call this mutation from your client-side application:

fetch('/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
  body: JSON.stringify({
    query: `
      mutation {
        addBook(title: "New Book", author: "New Author") {
          title
          author
        }
      }
    `,
  })
})
  .then(r => r.json())
  .then(data => console.log('data returned:', data));

4. Summary

In this tutorial, you've learned how to:
- Create mutations in a GraphQL schema
- Invoke these mutations from a client-side application

Next, you can learn more about GraphQL types, how to use variables in mutations, and more advanced topics like error handling and optimistic UI updates.

Additional resources:
- GraphQL Official Documentation: https://graphql.org/
- Apollo GraphQL Docs: https://www.apollographql.com/docs/

5. Practice Exercises

Exercise 1: Create a mutation for deleting a book by its title. Test this mutation by deleting a book that you've added.

Solution:

Define the mutation in your schema:

type Mutation {
  deleteBook(title: String!): Book
}

Add a resolver for the mutation:

deleteBook: ({ title }) => {
  const book = books.find((book) => book.title === title);
  books = books.filter((book) => book.title !== title);
  return book;
};

Exercise 2: Extend your schema with a mutation for updating a book's author. Test this mutation by updating a book that you've added.

Solution:

Define the mutation in your schema:

type Mutation {
  updateBook(title: String!, author: String!): Book
}

Add a resolver for the mutation:

updateBook: ({ title, author }) => {
  const book = books.find((book) => book.title === title);
  if (book) {
    book.author = author;
  }
  return book;
};

Remember to practice more and more to get a strong hold on the concept. Happy Coding!