Nested mutations provide a transactional boundary. This document outline how nested mutations, permission queries and operationBefore/operationAfter functions fit together.
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:
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 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 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.
What about subscriptions (both client and server)? I think they should also be delayed until after the transaction commits.
Also, it's important to note somewhere in the docs that before operations should be 'pure', e.g. without side effects, for this to work properly.
Superceded by #1280.
Most helpful comment
What about subscriptions (both client and server)? I think they should also be delayed until after the transaction commits.
Also, it's important to note somewhere in the docs that before operations should be 'pure', e.g. without side effects, for this to work properly.