GraphQL Mutations Tutorial

Summary

The configuration and settings in LogScale can be changed or deleted using GraphQL mutations. Many administrators use the UI to do these tasks, but they all can be performed from the commmand-line or as part of custom programs and scripts using the GraphQL API.

Administrators and other authorized users may need to add or remove users, groups, and roles, which include permissions. They will also need to modify the configuration of a LogScale instance, as well as alerts and other actions. They can do this with the GraphQL API.

This page covers basic mutation syntax and how to execute a mutation and get results. For instructional purposes, generic mutations are used. Actual mutations include more components, and involve complexity that can be confusing when first learning about them. The goal here is to learn the basics of mutations.

Simple Generic Mutation

To begin, consider a very generic mutation — a fictitious one — called, addThing(). It's meant to add a given thing to a list of things stored in LogScale. Below is what its syntax might be:

graphql
addThing( 
      name: string!,
      enabled: boolean
         ): boolean

The syntax shows the input within parentheses — the spacing and line-breaks aren't necessary. Input is always given with a key and a value: the name is a key. You would give the name of the thing, the value as a string, within double-quotes. For the enabled value you would enter true or false. However, there isn't an exclamation mark after it. That means the parameter and value are not required. The default value would be used if not provided.

Exclamation marks are not typed. Neither is the colon after the closing parenthesis entered. Since the results in this syntax use a boolean, you don't enter anything for it. Here's how this fake mutation might be entered:

graphql
query {
      addThing( name: "thing-five" )
   }

If this was an actual mutation, you might enter it in the API Explorer, which is covered in another tutorial. Below are the imagined results from the mutation:

graphql
{
  "data": {
    "addThing": true
    }
}

These results indicate that the addition of the thing was successful. To get information on the thing added, you would use the fake query, thing(). It's covered in the Query Tutorials tutorial. For a list of things, there might be a things() query.

Generic Datatype

The previous fictitious mutation is very simple. Most mutations, though, involve special datatypes — not just strings, booleans, or integers. Suppose the engineers that design LogScale decide to make a new version of addThing(), to replace it. They would mark the old version as deprecated, but it will still be useable for many weeks before it's eliminated. The new version would be called something like, addThingV2() — which is a common naming pattern they use. Here's its contrived syntax:

graphql
addThingV2( 
      name: string!,
      enabled: boolean
         ): Thing!

This uses an imagined datatype called, Thing. In the documentation that would accompany this mutation, a table would be provided with its components. Here's how that might look:

Table: Thing Datatype

Parameter Type Required Default Description
description string     A description of the thing.
enabled boolean yes   Whether the thing is enabled.
id string yes   The unique identifier of the thing.
name string yes   The display name of the thing.

As you can see in the table above, there are four possible values that are stored using the Thing datatype, four values that you can request in the results. You'll notice that two are required and two are not. This doesn't mean you're required to request them. Instead, it means that some value must be stored in the fields that are required and the others can be null.

For the special datatype, you would list within curly-braces the keys for the values you want returned after executing the mutation. Here's how that might look:

graphql
query {
      addThingV2( name: "thing-six" )
      { name, id, enabled }
   }

The system will assign a unique identifier for the thing added. Here are the imagined results:

graphql
{
  "data": {
    "addThingV2": [
      {
        "name": "thing-six",
        "id": "mno123",
        "enabled": true
      }
}

This is in a json format that you can interpolate into variables in a custom program or script. Notice that it shows the thing is enabled, although that wasn't specified in the input for the mutation. That's because it has a default value.

Generic Update

When there is a mutation to add a thing, besides a query or two to get information on things, there is usually a mutation to change a thing, and another delete it. There can also be a pair of mutations to enable and disable things.

To continue with these generic examples, suppose there is a mutation called, updateThing(). Here's how that might look in use:

graphql
query {
      updateThing( 
         id: "abc123",
         description: "The First Thing" )
      { name, enabled }
   }

The mutation changes, or rather gives a description to thing-one. Notice the example gives the unique identifier for the thing, which first can be obtained from the related queries. Here are the supposed results of this mutation:

graphql
{
  "data": {
    "updateThing": [
      {
        "name": "thing-one",
        "enabled": true
      }
}

Conclusion

There are more possibilities with mutations: how their syntax is composed, the use of special datatypes for the input, the use of sub-datatypes for input and the results. This was only a start for understanding mutations and how they work.