Bulk insert mutations with GraphQL
Tags: graphql, tutorial, webdev
Published: 2019-12-20 09:48:23

---
title: Bulk insert mutations with GraphQL
published: true
date: 2018-08-12 00:00:00 UTC
tags: graphql, tutorial, webdev
canonical_url: https://blog.hasura.io/bulk-insert-mutations-with-graphql-e22727ce5b12/
---

### GraphQL insert mutations are used to create new objects in your back-end (typically a database) which can then be queried.

![](https://blog.hasura.io/content/images/downloaded_images/bulk-insert-mutations-with-graphql-e22727ce5b12/1-8x4j7cCK_mtsl6_K0buCAQ.jpeg)

In any typical application, you will often need to insert multiple objects into the database in one go. These could be objects of the same type or objects of different types.

Some things to keep in mind in such a scenario would be:

- How many network requests are needed to achieve the inserts?
- How many and how efficient are the insert queries that will actually be run on the database?
- Is each insert independent of others? i.e. is the order of execution important.
- If some of the inserts fail, what happens to the rest of the inserts? Should the rest of the inserts go through or should all the inserts be rolled back?

### The Hasura GraphQL engine

The [Hasura GraphQL engine](https://github.com/hasura/graphql-engine) provides instant GraphQL APIs over any [Postgres database](https://hasura.io/learn/database/postgresql/what-is-postgresql/).

With the above points considered, the Hasura GraphQL engine provides the following features for bulk insert mutations which guarantee a high performance and that the database is always in a consistent state:

- multiple objects of the same type can be inserted using a single insert mutation field within a mutation. This will be executed as a single SQL statement in the database.
- multiple objects of different types can be inserted using multiple insert mutation fields within the same mutation.
- if there are multiple mutation fields within a mutation, they will be executed sequentially on the database.
- if any of the mutation fields within a mutation fail, all the mutation fields in that mutation will be rolled back. i.e. all the mutation fields within a mutation are run as a **transaction**.

Let us assume we have the following tables in our database:

 {% gist https://gist.github.com/rikinsk-zz/eb09563688c516730748c993260115db.js %}

The following are the insert mutation fields generated by Hasura GraphQL engine for the above tables:

 {% gist https://gist.github.com/rikinsk-zz/e0d2909eafe838417b9751f0b7540390.js %}

As you can see, the insert mutation fields expect an array of objects to be passed as arguments which will be inserted into the database.

Now let’s see a few examples of bulk insert mutations using the Hasura GraphQL engine:

### Insert multiple objects of same type

**Example** : Insert `authors` in bulk using a single `insert_author` mutation field in a mutation:

 {% gist https://gist.github.com/rikinsk-zz/1d75cd0e4df99994e013719a90752fd1.js %}

**Notes:**

- If insertion of any row fails (for example due to a duplicate [primary key](https://hasura.io/learn/database/postgresql/core-concepts/5-postgresql-primary-key/)), none of the rows will get inserted.

### Insert multiple objects of different types

**Example** : Insert `author` and `articles` written by that `author` using the `insert_author` and `insert_article` mutation fields in the same mutation:

 {% gist https://gist.github.com/rikinsk-zz/228087fbc287ff0d9052349a00b5cfed.js %}

**Notes:**

- In this example, the `articles` can be inserted only after the `author` is inserted as it would otherwise violate the `author_id` foreign key constraint. Hence the sequential execution of inserts is necessary here.
- If the inserting of `author` fails, the execution of the entire mutation halts and inserting of `articles` is not even attempted.
- If the inserting of `articles` fails, the insertion of the `author` is rolled back and the database state is restored to what it was before the mutation was attempted.