📙 The architect's guide to building scalable global applications |
Learn more
Fauna logo
Log InContact usStart for free
Fauna logo
Log InContact usStart for free
© 2023 Fauna, Inc. All Rights Reserved.

Related posts

Building an edge serverless GraphQL backend with Cloudflare Workers and FaunaBuilding scalable solutions with Apollo Federation and FaunaHow to use Fauna with GraphQL and PHP

Start for free

Sign up and claim your forever-free Fauna account
Sign up and get started

Request demo

Connect with a Fauna expert
request demo

Table of Contents


Best practices for GraphQL mutations

Nov 13th, 2021|


When you mention GraphQL queries, everyone only thinks about querying data. However, applications also need to support full CRUD behaviors, enabling actions like updating and deleting data. This means that there is more than GraphQL APIs need to do.
In a GraphQL API, a user can perform three types of operations: queries, subscriptions, and mutations. GraphQL queries are used to fetch data from a server. Subscriptions are long-lived requests that fetch data in response to certain trigger events. Finally, a mutation is used to write or modify server-side data.
In this guide, we will delve deeper into GraphQL mutations, how they are structured and defined, and some of the best practices involved in using GraphQL mutations.

What are GraphQL mutations?

Before getting into mutations, let’s introduce GraphQL.
GraphQL is a query language for interacting with APIs. In recent years, it has grown in popularity as a more flexible and performant alternative to traditional REST APIs for certain use cases.
In GraphQL, mutations are used to create or modify server-side data. This means that they are used to “mutate,” or change information on the server. This is equivalent to the state-changing REST methods(DELETE, PUT, POST, and PATCH).

How to use mutations in GraphQL

Understanding the structure of a GraphQL query and how these GraphQL operations work will be helpful when we discuss some of the best practices for designing GraphQL mutations in the following section.
The graphic below outlines the structure of the GraphQL operation. First the operation type is specified. Next, every operation is assigned its own unique name. In this example HeroNameAndFriends is the operation name. In some cases, operations may also require variables to be passed in as arguments. These variables are specified in the variable definition. In this case, the variable is $episode, which is of the type Episode.
Variable definitions are expressed in the form ($variable_name: VariableType). You can include multiple variable definitions by adding them as comma-separated values.
The operation types can be either a query, subscription, or mutation. The following example illustrates a query operation that fetches data in the same structure specified in the operation.
query HeroNameAndFriends ($episode: Episode) {
hero(episode: $episode){
The following example illustrates a mutation operation. We signal the mutation method that we want to invoke by naming it exactly as it occurs within our server-side GraphQL API. Here, the addBook mutation creates a mutation that adds a book to an API that stores the book in a library. Information about the title and author are provided to the mutation through the variable definitions ($title: String!, $author: author).
mutation AddNewBook ($title: String!, $author: author) { 
  addBook(title: $title, author: $author) {
Like queries, mutations also return data. Mutations, however, will only return new data that is created. After the mutation is successfully executed, the created book is returned by the API in the format:
For this mutation, named addBook, to be successfully registered in our GraphQL API, it would also have to include a GraphQL API type definition in the root mutation object as shown below:
type Mutation {
  addBook (title: String!, author: author): AddBookResult!
The structure includes the name of the mutation, the variable definitions and the result of the mutation. Here the variables are defined as (title: String!, author: author). The trailing ! is used to specify required variables for the mutation. For this mutation to be successfully executed, you must pass in a String value for the title. However the author field is optional. Similarly, the AddBookResult! Return type specifies that this mutation must always have a return value.

Best practices for GraphQL mutations

In general, mutations represent actions on an object. Here are some key best practices for GraphQL mutations :
  1. Use short, but descriptive names to describe the mutation actions. The easiest and best way to represent mutations is to start with an action verb first followed by the name of the object that the action is being applied to. For example, mutations such as addBook, createUser, resetPassword and refreshFeed are very clear about what the mutation operation will do and on what object.
  2. For better readability, name the mutations with the object first. Some APIs may support similar operations on multiple object types. For example, your API might create objects of types User, Author, and Book. In these cases, it may be more useful to name your mutations with the object’s name first, such as userCreate, authorCreate, and authorCreate.
  3. Use more specific names for actions. For example, let’s say that your application needs to reset and send the password for a particular email account. Naming the operation sendResetPasswordEmail is more intuitive and specific than sendEmail(type: PASSWORD_RESET). The latter choice could imply multiple mutations named sendEmail with varying variable definitions. With more specificity in the naming convention, it becomes easier for a UI developer to build the frontend because they will know exactly which mutation to run. Backend developers can also optimize their APIs by only providing a specific subset of mutations that do only certain things. Because of this design, attackers will have a much harder time exploiting the API than if the mutations were named more generically.
  4. Try to ensure that your mutation uses a single argument object. Rather than have multiple individual objects, create a single object that is nested as much as possible to include all the required fields. Updating the addBook mutation to use a single nested input object should look like this:
mutation AddNewBook (input: AddBookInput!) { 
  addBook($input: $input) {
The underlying title and author fields are wrapped in a single AddBookInput object type instead of being individually specified.
type AddBookInput {
  title: String!
author: author
 # Additional fields can be added to this single object.
As a result, any existing schema design can be easily extended by adding more nested subfields to the input object rather than updating the whole structure of the mutation to include more fields. Similarly, you can deprecate unnecessary fields in your input object by simply removing the nested subfield.


In a GraphQL API, queries are used to fetch data from a server, while mutations are used to modify or write server-side data. Therefore, it is essential to understand its structure when defining a mutation, including the type definition, the mutation name, and variable definitions. For better results when using mutations, keep in mind some of the best practices discussed in this blog.
While GraphQL has been welcome competition for REST, it’s critical that developers can use GraphQL to query and mutate data from their databases. Fauna is a flexible, developer-friendly, serverless database delivered as a secure and scalable cloud API with a native GraphQL interface. It’s free to try and takes minutes to spin up a new database.
Sign-up for free The data API for modern applications is here. Sign-up for free without a credit card and get started instantly. Sign-up now
Quick start guide Try our quick start guide to get up and running with your first Fauna database, in only 5 minutes! Read more

If you enjoyed our blog, and want to work on systems and challenges related to globally distributed systems, serverless databases, and GraphQL, Fauna is hiring!

Share this post

‹︁ PreviousNext ›︁

Subscribe to Fauna's newsletter

Get latest blog posts, development tips & tricks, and latest learning material delivered right to your inbox.