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
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.
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.
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
}
}
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));
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/
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!