This content originally appeared on DEV Community and was authored by Matteo Kovačić
When we started working with GraphQL, we experienced common issues like N+1 problem, error handling, etc. As our API started growing, new challenges occurred. They were mostly related to the schema design and how to have a schema that is easy to read and also functional.
By specification, GraphQL allows us to send multiple mutations in a single request and these mutations will be executed in the order in which they were sent. GraphQL specification doesn't guarantee us that if some of these mutations fail, all others will fail as well. In other words, GraphQL doesn't specify that all mutations should be executed in the transactions. Luckily, this can be easily enabled in the Overblog GraphQL Bundle using built-in events.
First, in services.yaml
, you need to register the event listener for two events: graphql.pre_executor
and graphql.post_executor
.
services:
...
App\EventListener\GraphQLExecutorListener:
tags:
- { name: kernel.event_listener, event: graphql.pre_executor, method: onPreExecutor }
- { name: kernel.event_listener, event: graphql.post_executor, method: onPostExecutor }
Then, in the event listener, you have a method for each event. In onPreExecutor we start the transaction. After mutations are resolved, in onPostExecutor we commit the changes if there are no errors or rollback if an error occurred.
class GraphQLExecutorListener
{
private EntityManagerInterface $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public function onPreExecutor(): void
{
$this->entityManager->getConnection()->beginTransaction();
}
public function onPostExecutor(ExecutorResultEvent $event): void
{
$connection = $this->entityManager->getConnection();
if ($connection->isTransactionActive() === false) {
throw new LogicException('Transaction not active');
}
if (count($event->getResult()->errors) > 0) {
while ($connection->getTransactionNestingLevel() > 0) {
$connection->rollback();
}
return;
}
$connection->commit();
}
}
That's it, all mutations should now be executed in the transaction.
If necessary, the event listener can be extended to conditionally enable the transaction, for example using a header or some other flag.
This content originally appeared on DEV Community and was authored by Matteo Kovačić
Matteo Kovačić | Sciencx (2021-07-06T11:43:26+00:00) How to execute multiple GraphQL mutations in a transaction using Overblog GraphQL Bundle. Retrieved from https://www.scien.cx/2021/07/06/how-to-execute-multiple-graphql-mutations-in-a-transaction-using-overblog-graphql-bundle/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.