-
Notifications
You must be signed in to change notification settings - Fork 851
Transactional Guarantees for Nested Mutations #597
Description
Nested mutations provide a transactional boundary. This document outline how nested mutations, permission queries and operationBefore/operationAfter functions fit together.
Nested Mutations
A nested mutation contains multiple CRUD operations in a single GraphQL mutation:
mutation {
createUser(
name: "Søren Bramer",
articles: [
{title: "My first article"}
{title: "My second article"}
])
}
This nested mutation performs 5 crud operations:
- create User node
- create Article node
- create Article node
- connect Article and User
- connect Article and User
These operations should either all succeed or not succeed at all.
Additionally, any other query running at the same time should either see the result of all operations or none.
Permission Queries
Permission queries are a convenient way to write permission rules that depend on data relations.
The following permission query gives access when an Article is related to the User called 'Søren Bramer':
{
someArticleExists(filter: {id: $node_id, author: {name: "Søren Bramer"}})
}
If this permission governs UPDATE
access, the permission query can be executed before the database transaction.
If the permission governs CREATE
access the situation is a bit more tricky. In the nested mutation above we can not perform the permission query before the database transaction, as the user Søren Bramer
does not exist until after the transaction has been performed.
The solution is to open a transaction, perform all the writes, keep the transaction open while performing the permission query, and then either commit or roll back the transaction depending on the result of the permission query.
Permission queries will default to run before the transaction, but the developer can configure a specific permission query to always run at the end of the transaction.
operationBefore/operationAfter functions
operationBefore and operationAfter functions are specified for a specific model. If multiple operations exist for the models involved in a nested mutation, all operations are performed together before and after the database transaction respectively.
Overview
- All operationBefore
- All permission queries that should run before
- Transaction start + write
- All permission queries that should run after
- transaction commit or rollback
- if transaction commit: All operationAfter