When writing a mutation resolver for Graphql-yoga ...
# prisma-whats-new
b
When writing a mutation resolver for Graphql-yoga -> Prisma, what's the best way to ensure integrity? For instance, I want to move a coin from player1's account, if it exists, to player2's, but not have problems with coins replicating or disappearing.
d
I think I've read somewhere that nested mutations are atomic
b
Awesome!
d
haven't tested that tho, not sure how reliable it is 🙂
b
A paragraph in the docs is all the assurance I need. 🐿️
So how would you wrap multiple updates in the same mutation? If you do something like this:
Copy code
mutation{
  a: updatePlayer(
    where:{name:"p1"}
  	data:{totalCoins:2})
  {
    name
  	totalCoins
  }
  b: updatePlayer(
    where:{name:"no-exist"}
    data:{totalCoins:3}
  )
  {
    name
    totalCoins
  }
}
"a" goes through even if "b" fails.
n
That's an interesting discussion, thanks for bringing it up @Bro. We are thinking about supporting transactions across multiple top level mutations. There has been some discussion about that here:https://github.com/graphcool/prisma/issues/74 Would love to hear your take on this in the issue 🙂
b
I was reading that earlier. Will do.
🙏 1
Harmony and I were discussing this in a thread today. One of the problems with this case would be double spending. It looks like you would need to wrap a query as well as both mutations in a transaction to ensure that the resolver wasn't hit multiple times. It may be better have the resolver make a custom sql call directly on the database or through Prisma, if that becomes a feature. Especially if you start doing more complicated exchanges.
n
That's certainly a possible approach. We're exploring raw SQL queries as a general fallback strategy already, and will detail our thoughts here soon: https://github.com/graphcool/prisma/issues/2052.
b
I commented on issue 74. To summarize: I can almost accomplish this with nested queries, but can't guarantee that double spending won't take place. If there was something in addition to
where: PlayerWhereUniqueInput!
like an optional
andWhere: [PlayerWhereInput!]
you would be able to check some other conditions. The same would hold true for transactions across multiple top level mutations.
n
thanks for your input! 🙂 for now, you can also think about locking the mutation in your GraphQL Server layer instead
b
Currently, the solution I came up with was adding a
lastState: someUUID
property to the player type, that would be changed on every update. That way, the
where: PlayerWhereUniqueInput
would verify the last known state returned from the preceding query and nested mutation transactions would take care of the rest. I'm not sure if this was the type of pattern the Prisma developers had in mind or not.