Atomic set and increment operators for GraphQL mutations
Tags: graphql, tutorial, postgres
Published: 2019-12-10 11:45:08

---
title: Atomic set and increment operators for GraphQL mutations
published: true
date: 2018-08-13 00:00:00 UTC
tags: graphql, tutorial, postgres
canonical_url: https://blog.hasura.io/updating-data-using-mutations-on-hasura-graphql-87c7e22503bc/
---

When using GraphQL, writes or updates to data are made via mutations. In this post we will discuss the update mutations and related operators that are available on the [Hasura GraphQL Engine](https://hasura.io).

![](https://blog.hasura.io/content/images/downloaded_images/updating-data-using-mutations-on-hasura-graphql-87c7e22503bc/1-yMbKmCoxIJ4CLO5aHQi-aQ.png)

**TL;DR:**

- Hasura allows you to update multiple objects in one shot using a powerful `where` argument which allows you to create a boolean filter to select the objects to be updated
- Hasura supports a `set` operator to set or replace an existing value
- Hasura supports an `increment` operator to atomically increment numerical values by a given amount to prevent common race conditions where multiple clients are incrementing the same attribute
- Hasura supports native JSON/JSONB operators that you can use to modify attributes in a JSON/JSONB value of a postgres column without needing to `set` the full JSON value

## Schema and generated mutations

Let’s consider the following schema for our example:

{% gist https://gist.github.com/ecthiender/0fd7df0207967b2f3bb3cb627790f8e4.js %}

When the above tables are tracked in Hasura GraphQL Engine, it will automatically generate the following update mutations:

{% gist https://gist.github.com/ecthiender/9db7f948715e5117d6d4cc67df3b35ee.js %}

As you can see above, there are 3 key arguments in the update mutation, `_set` , `_inc` and `where`.

`where` is a boolean expression, which is mandatory. `where` will help you select the rows on which the mutation is to be applied. Otherwise the update mutation will have to be applied for all rows in the table or only on one particular row, either of which are not particularly flexible options. You can read more about “bulk update” mutations here: [https://blog.hasura.io/bulk-update-and-delete-mutations-in-graphql-6568f47ad0b9](https://blog.hasura.io/bulk-update-and-delete-mutations-in-graphql-6568f47ad0b9)

You can look into the generated mutations in detail at: [https://hge-update-mutations.herokuapp.com/console](https://hge-update-mutations.herokuapp.com/console)

## Using `the "_set"` operator

The `_set` operator “sets” the value of one or more columns of a row by replacing the existing value. Consider 2 illustrative examples below:

Let’s say we want to update the title and content of an article that the user is editing. We can run the following GraphQL query using the `_set` operator (assuming we know the id of the article) :

{% gist https://gist.github.com/ecthiender/85cc17bc34a2485c7335430d6949dc64.js %}

If we want to update all articles of an author, i.e. update data using nested objects’ fields, our query would be like the following:

{% gist https://gist.github.com/ecthiender/1c49fea6331e313c03e4f0ab2c378fed.js %}

## Using `the "_inc"` operator

The \_inc operator atomically increments the existing value of one or more columns by a given amount. This operator is only for columns that have a “numeric” type, like integer, numeric, float, double etc.

Let’s say we want to update the likes of an article. As it is a numeric field, we can take advantage of the `_inc` operator. We can run the following GraphQL query (assuming we know the id of the article) :

{% gist https://gist.github.com/ecthiender/dea2ce20f51aba01e70117df2b1c2634.js %}

### Why do we need “\_inc”?

The advantage of using `_inc` is we can avoid race conditions.

If we were using `_set` directly — fetch previous likes, increment them on the client, and then run a set query with the new value — which can lead to race conditions when two clients simultaneously fetched the same likes and tried to update. One of our likes will be lost. As the `_inc` query is guaranteed to run atomically, we know that using that we will not run into race conditions.

## Using mutations to update JSON/JSONB data

Hasura GraphQL Engine has first-class support for updating JSON/JSONB data in your Postgres tables. You don’t have to form the JSON in your client and use `_set` . You can directly use any of `_prepend`, `_append`, `_delete_key`, `_delete_elem`, and `_delete_at_path` operators to update nested keys and values in your JSON data.

You can read more about these operators in this blog: [https://blog.hasura.io/postgres-json-and-jsonb-type-support-on-graphql-41f586e47536](https://blog.hasura.io/postgres-json-and-jsonb-type-support-on-graphql-41f586e47536)