GraphQL Mutation

In this section you will learn about GraphQL Mutation with examples.

GraphQL Mutation
GraphQL Mutation
GraphQL Mutation

Luke Stephens

Luke Stephens

Luke Stephens

What is a GraphQL Mutation?

GraphQL Mutations serve as the mechanism to change data on the server. Unlike REST, which exposes a fixed set of CRUD (Create, Read, Update, Delete) operations for each resource via HTTP methods, GraphQL mutations can be tailored to match the server's data operations.

  • Operation Name Significance: Naming your operations not only helps in debugging but provides a clearer understanding of the operation's intent, making your code more readable.

  • Variable Usage: Variables in GraphQL allow for dynamic input values in your mutations. They help in reusing the same mutation structure for different input values, making your code DRY (Don't Repeat Yourself).

GraphQL Mutation Types

GraphQL primarily supports three types of mutations:

  1. Create: For creating new records.

mutation CreateAuthor($name: String!) {
  createAuthor(name: $name) {
    id
    name
  }
}
  1. Update: For updating existing records.

mutation UpdateAuthor($id: ID!, $name: String!) {
  updateAuthor(id: $id, name: $name) {
    id
    name
  }
}
  1. Delete: For deleting records.

mutation DeleteAuthor($id: ID!) {
  deleteAuthor(id: $id) {
    id
  }
}

Input Types

Input types are a way to package multiple input values into a single complex object. This is useful when a GraphQL mutation requires multiple input values.

input AuthorInput {
  name: String!
  age: Int
}

mutation CreateAuthor($input: AuthorInput!) {
  createAuthor(input: $input) {
    id
    name
    age
  }
}

Basic GraphQL Mutation

A mutation in GraphQL has a clear, easy-to-follow structure. It starts with the keyword mutation, followed by the operation name, input values, and the data you want to return.

  • Description: This structure enables the client to specify exactly what data should be returned after the mutation, reducing the need for subsequent queries.

  • Example: In this mutation, we're creating a new book and asking for the book's id and title in return.

mutation CreateBook($title: String!, $author: String!) {
  createBook(title: $title, author: $author) {
    id
    title
  }
}

Visual Aids

  • Flow Diagrams: Incorporate flow diagrams to illustrate the journey of a GraphQL mutation request from the client to the server, and back to the client.

  • Code Annotations: Annotate code snippets to explain the significance of each part of the mutation syntax. For instance, explain the mutation keyword, the operation name, and the structure of the input values.

Common Pitfalls of GraphQL Mutation

  • N+1 Problem: GraphQL can suffer from the N+1 problem where the server executes multiple unnecessary queries.

  • Error Handling: Not handling errors properly can lead to misleading client-side issues. Always ensure errors are handled and communicated back to the client clearly.

Specifying GraphQL Mutation Responses

In GraphQL, you can specify the exact shape of the response you want to get from a mutation, enabling you to retrieve newly created or updated data without making additional requests.

  • Description: This is a powerful feature that ensures you get all the necessary data back in a single request.

  • Example: In the following mutation, we're updating a book's title and requesting the updated title and author in return.

mutation UpdateBook($id: ID!, $newTitle: String!) {
  updateBook(id: $id, title: $newTitle) {
    title
    author
  }
}

Error Handling in GraphQL Mutations

Error handling is crucial in mutations to ensure that any issues are clearly communicated back to the client.

  • Description: Similar to queries, errors in mutations are returned in an errors array in the response.

  • Example:

{
  "errors": [
    {
      "message": "Book not found",
      "locations": [
        {
          "line": 2,
          "column": 7
        }
      ]
    }
  ]
}

Comparison with REST

In REST, CRUD operations are mapped to HTTP methods:

Each operation is performed on a specific URL, and the server determines the structure of the response. On the other hand, GraphQL mutations allow for a more flexible interaction, enabling clients to specify the structure of the response, even after a mutation. This comparative flexibility can lead to more efficient interactions with the server.

# GraphQL
mutation CreateBook($title: String!, $author: String!) {
  createBook(title: $title, author: $author) {
    id
    title
    author
  }
}
# REST
POST /books
{
  "title": "New Book",
  "author": "Author Name"
}

In the GraphQL example, the client specifies the data it needs in the response, whereas in the REST example, the server determines the structure of the response.

GraphQL Mutation Request Example

Mutations in a real-world scenario follow a structured approach, defining the operation, input values, and desired response shape.

  • Operation Name: Naming your mutation aids in debugging and server-side logging.

    Example:

mutation AddNewBook
  • Mutation String: Specifies the mutation operation and the data you want to return.

    Example:

mutation AddNewBook($title: String!, $author: String!) {
  createBook(title: $title, author: $author) {
    id
    title
    author
  }
}
  • AddNewBook is the operation name for clarity and debugging.

  • ($title: String!, $author: String!) are the variables being passed to the mutation. They're used as input values for creating a new book.

  • createBook is the mutation field, with id, title, and author as sub-fields to return the created book’s details.

  • Variables: Dynamic values passed to the mutation.

    Example:

{
  "title": "To Kill a Mockingbird",
  "author": "Harper Lee"
}

GraphQL Mutation Response Example

The server processes the mutation request and returns a response containing the results of the mutation along with any errors.

  • Data: The data returned from the mutation, structured according to the request.

    Example:

{
  "data": {
    "createBook": {
      "id": "456",
      "title": "To Kill a Mockingbird",
      "author": "Harper Lee"
    }
  }
}
  • Errors: Any errors encountered during the mutation.

    Example:

{
  "errors": [
    {
      "message": "Author not found",
      "locations": [
        {
          "line": 3,
          "column": 5
        }
      ]
    }
  ]
}

Best Practices for Writing Mutations

  • Naming: Similar to queries, it’s important to choose descriptive names for your mutations and the input variables. This improves the readability and maintainability of your code.

  • Handling Server-side Validation: Ensure that server-side validation errors are handled gracefully.

  • Idempotency: Design your mutations to be idempotent where possible. This means that no matter how many times a mutation is run, the result should be the same.

Conclusion

This module has equipped you with the essential knowledge on GraphQL mutations, enabling you to create, update, or delete data on the server.