πŸŽ‰ Released Gato GraphQL v0.7, with support for mutations, and nested mutations!


Version 0.7 of Gato GraphQL, supporting mutations, and nested mutations, has been released! πŸŽ‰

Mutations are awesome!

Here is a tour showing the new additions.

1. Mutations! πŸš€

GraphQL mutations enable to modify data (i.e. perform side-effect) through the query.

Mutations was the big item still missing from Gato GraphQL. Now that it's been added, I can claim that this GraphQL server is pretty much feature-complete (only subscriptions are missing, and I'm already thinking on how to add them).

Mutation root in the interactive schema

Let's check an example on adding a comment. But first, we need to execute another mutation to log you in, so you can add comments. Press the "Run" button on the GraphiQL client below, to execute mutation field loginUser with a pre-created testing user:

mutation LogUserIn {
  loginUser(
    by: { credentials: { usernameOrEmail: "test", password: "pass" } }
  ) {
    id
    name
  }
}

Now, let's add some comments. Press the Run button below, to add a comment to some post by executing mutation field addCommentToCustomPost (you can also edit the comment text):

mutation AddComment {
  addCommentToCustomPost(
    input: { customPostID: 1459, comment: "Adding a comment: bla bla bla" }
  ) {
    id
    content
    date
  }
}

In this first release, the plugin ships with the following mutations:

βœ… createPost
βœ… updatePost
βœ… setFeaturedImageforCustomPost
βœ… removeFeaturedImageforCustomPost
βœ… addCommentToCustomPost
βœ… replyComment
βœ… loginUser
βœ… logoutUser

2. Nested Mutations! πŸš€πŸš€

Nested mutations is the ability to perform mutations on a type other than the root type in GraphQL.

They have been requested for the GraphQL spec but not yet approved (and may never will), hence Gato GraphQL adds support for them as an opt-in feature, via the Nested Mutations module.

Then, the plugin supports the 2 behaviors:

  1. The standard GraphQL behavior (i.e. adding mutation fields to the root type), by default
  2. Nested mutations, as an opt-in

For instance, the query from above can also be executed with the following query, in which we first retrieve the post via Root.post, and only then add a comment to it via Post.addComment:

mutation AddComment {
  post(by: { id: 1459 }) {
    addComment(
      input: {
        comment: "Notice how field `addCommentToCustomPost` under the `Root` type is renamed as `addComment` under the `Post` type? The schema got neater!"
      }
    ) {
      id
      content
      date
    }
  }
}

Mutations can also modify data on the result from another mutation. In the query below, we first obtain the post through Root.post, then execute mutation Post.addComment on it and obtain the created comment object, and finally execute mutation Comment.reply on it:

mutation AddCommentAndResponse {
  post(by: { id: 1459 }) {
    id
    title
    addComment(input: { comment: "Isn't this awesome?" }) {
      id
      date
      content
      reply(input: { comment: "I think so!" }) {
        id
        date
        content
      }
    }
  }
}

This is certainly useful! 😍 (The alternative method to produce this same behavior, in a single query, is via the @export directive... I'll compare both of them in an upcoming blog post).


In this first release, the plugin ships with the following mutations:

βœ… CustomPost.update
βœ… CustomPost.setFeaturedImage
βœ… CustomPost.removeFeaturedImage
βœ… CustomPost.addComment
βœ… Comment.reply

Standard or nested? Or both?

You may have a GraphQL API that is used by your own application, and is also publicly available for your clients. You may want to enable nested mutations but only for your own application, not for your clients because this is a non-standard feature.

Good news: you can.

I've added a "Mutation Scheme" section in the Schema Configuration, which is used to customize the schema for Custom Endpoints and Persisted Queries:

Mutation scheme in the Schema configuration

Hence, you can disable the nested mutations everywhere, but enable them just for a specific custom endpoint that only your application will use. πŸ’ͺ

Removing redundant fields from the root type

With nested mutations, mutation fields may be added two times to the schema:

  • once under the root type
  • once under the specific type

For instance, these fields can be considered a "duplicate" of each other:

  • Root.updatePost
  • Post.update

Gato GraphQL enables to keep both of them, or remove the ones from the root type, which are redundant.

Check-out the following 3 schemas:

  1. Standard behavior:
    it uses types QueryRoot to handle queries and MutationRoot to handle queries
  2. Nested mutations keeping mutation fields duplicate:
    a single Root type handles queries and mutations, and redundant mutation fields in this type are kept
  3. Nested mutations removing redundant mutation fields from the root type:
    same as above, but removing all redundant mutation fields from the Root type

✱ Btw1, these 3 schemas all use the same endpoint, but changing a URL param ?mutation_scheme to values standard, nested and lean_nested. That's possible because the GraphQL server follows the code-first approach. 🀟

✱ Btw2, these options can be selected on the "Mutation Scheme" section in the Schema configuration (shown above), hence you can also decide what behavior to apply for individual custom endpoints and persisted queries. πŸ‘


Now it's time to start preparing for v0.8! πŸ™


Want more posts & tutorials?

Receive timely updates as we keep improving Gato GraphQL.

No spam. You can unsubscribe at any time.