This
GraphQL is a complex language, and the information in this
What are Mutations?
Mutations are GraphQL operations that modify data in the system and then return a value. Typically, mutations create new data, update existing data, or delete existing data.
Mutation Types
Most mutations fall into one of three types:
- Create. These mutations add new data to your system.
- Update. These mutations update existing data on your system.
- Delete. These mutations remove existing data from your system.
There are also less common mutation types, such as Validate, Set, Upgrade, Duplicate, and Save.
To see a full list of mutations that are available for SL1, see the schema in the GQL browser.
Basic Mutation Syntax
The most basic syntax of a mutation involves the following elements:
- Operation type. For mutations, this is mutation. Unlike queries, the operation type is required when executing a mutation.
- Operation name. A name that you define for the operation. While operation names are not always required, they are helpful to have for logging and debugging purposes.
- Object. The mutation object, as defined in the schema. This is written as a verb—typically "create", "update", or "delete"—followed by the name of the object you are mutating, written together in camel case. For example, if you wanted to create a new physical device, you would use the object createPhysicalDevice. If you wanted to update an existing system process monitoring policy, you would use the object updateMonitorSystemProcess.
- Argument(s). The data that you want to pass to the database through the mutation. These are defined in the following structure: (fieldName: value"). The schema lists the argument field name and value type pairs that are available for each mutation field. Depending on the specific mutation, it might have no arguments, one argument, or multiple arguments. If it has multiple arguments, the argument structure is (fieldName: "value", fieldName: "value"), with any additional arguments separated by additional commas.
- Return field(s). The fields that you want GraphQL to return when you execute the mutation. For example, you might include a return field if you want to see the new state of an object after an update.
If you mutate multiple objects, GraphQL executes the mutations on those objects in sequence, one after the other.
Example: Updating a User's Name
Here is an example of a basic mutation. In this example, we are updating the name of an existing SL1 user:
mutation updateUserID {
updateAccount(id: "11", user: "Example User", acceptedEula: true) {
id
user
acceptedEula
}
}
In this example:
- mutation is the operation type.
- updateUserName is the operation name that we defined for this specific operation.
- updateAccount is the object. We are telling GraphQL that we want to update an existing user account in SL1.
- id: "11", user: "Example User", and acceptedEula: true are the arguments that we are passing to the database. We are telling GraphQL that the user account we want to update has the user ID "11", and that we want to update that user's name to "Example User" and indicate that the user has accepted the SL1 end user license agreement.
- id, user, and acceptedEula are the return fields. We are telling GraphQL that, after it mutates the specified user account, we want it to return the user's ID and name, as well as confirmation the user is marked as having accepted the SL1 end user license agreement, so that we can verify the information.
When we execute this mutation, GraphQL returns the following, confirming that the mutation has updated the fields that we told it to:
{
"data": {
"updateAccount": {
"id": "11",
"user": "Example User",
"acceptedEula": true
}
}
}
Variables
Just like with queries, you can use variables to dynamically replace arguments in mutations, enabling you to reuse the mutation for multiple objects simply by changing the variable value.
The same rules apply to using variables in mutations as in queries.
Example: Using Variables in a Mutation
In this example, we are taking the same mutation that we executed in the previous example and replacing the defined argument values with variables. This enables us to use the same mutation numerous times to add multiple new users by simply re-defining the variable values as needed:
mutation updateUserID($id: ID!, $userName: String!, $Eula: Boolean = true) {
updateAccount(id: $id, user: $userName, acceptedEula: $Eula) {
id
user
acceptedEula
}
}
We must then define these variables. To do so, we would type their values into the Variables pane in the GQL browser in the following format:
{"id": "11", "userName": "Example User"}
In the above example, we did not define the $Eula variable because we declared a default value of true for it in our mutation. If we had wanted instead to pass a value of false, then we would have specified that with the other variable definitions in the Variables pane.
Fragments
Similar to their use in queries, you can use fragments in mutations to group together a set of fields associated with a particular type that you can then reuse to define return fields in multiple mutations.
The same rules apply to using fragments in mutations as in queries.
Example: Using a Fragment in a Mutation
In this example, we are taking the same mutation that we executed in the previous example and replacing the return fields id, user, and acceptedEula with the fragment accountInfo. This enables us to use the same return fields every time we use that mutation to add a new user:
fragment accountInfo on Account {
id
user
acceptedEula
}
mutation updateUserID($id: ID!, $userName: String!, $Eula: Boolean = true) {
updateAccount(id: $id, user: $userName, acceptedEula: $Eula) {
...accountInfo
}
}
Directives
You can use directives to make GraphQL perform custom logic in your mutations, just as you can in queries. They can be attached to a field or a fragment that you are including in your mutation, and can affect the data that GraphQL displays when you execute the mutation.
The same rules apply to using fragments in mutations as in queries.
Example: Using a Directive in a Mutation
In this example, we are taking the same scenario and fields as in the first example, with one exception: this time, we are not marking the user as having accepted the SL1 end user license agreement by passing the argument acceptedEula: true to the updateAccount mutation, as we did previously.
We are still going to include the acceptedEula return field, however. This will inform us whether the user has already accepted the SL1 end user license agreement without us having done it for them.
But in this scenario, we are only concerned with users who have not accepted the license agreement. Therefore, we are going to include a directive to skip the inclusion of the acceptedEula return field if GraphQL determines that the value is already true:
mutation updateUserID {
updateAccount(id: "11", user: "Example User") {
id
user
acceptedEula @skip(if: true)
}
}
As you can see, because that user account has already accepted the license agreement, GraphQL does not return the acceptedEula field when we execute the mutation:
{
"data": {
"updateAccount": {
"id": "11",
"user": "Example User"
}
}
}