Tradeoffs when designing GraphQL Mutations to update multiple Properties on one Entity

Nik Graf
InstructorNik Graf
Share this video with your friends

Social Share Links

Send Tweet
Published 4 years ago
Updated 3 years ago

While being specific is great when designing GraphQL Mutations, in some cases this can lead to a large number of Mutations. Especially when the use-case is to update one entity, it raises the question if can or should do just one update mutation.

It's certainly possible, but requires some tradeoffs. Most commonly we have to make non-nullable fields nullable. In this lesson we use an updateProduct example to elaborate why this tradeoff is needed.

Instructor: [0:00] In our Web shop, admins have to be able to update a product. A simple form with input fields and a save button should do. One thing we could do is create a mutation for each of the input fields, updateProductName, updateProductDescription, and updateProductImage.

[0:18] To update the recommended products, we already learned it's better to have two mutations, addRecommendedProducts to product and removeRecommendedProducts from product. These are a lot of mutations, especially when you consider these are just to update one entity, the product. This brings up a question. Can or should we use an updateProduct mutation instead? Yes and no.

[0:46] We can create such a mutation, but there are some tradeoffs involved. Shipping it to production is fine as long as it is an informed and conscious decision. Let's explore the tradeoffs based on an example.

[0:59] We create an updateProduct mutation with one input. The payload should include a product. Our input should include the product ID and the fields that can be updated. For now, we only focus on name and description.

[1:30] In order to verify our approach, let's implement it. We add the mutation, updateProduct. With it, we create an updateProductInput as well as an updateProductPayload. We can copy our example mutation and verify if it works as expected.

[2:11] Right now, we updated both fields. What if we only want to update the name? What? Why even do that? Let me explain. Once there are multiple admins that can update a product, the client should only communicate the input fields that changed, to avoid that admins override each other's changes.

[2:33] In case we only want to update the name, we leave out the description. This even works because description is not a mandatory field in updateProductInput. At this point, you might think, "Wait a minute. I thought leaving out the exclamation mark means a field can be nullable."

[2:53] Yes, you are correct, but for inputs it actually means that the field can be omitted or set to null. This wasn't always the case but was added in October 2016 when the null value RFC got merged into the GraphQL specification. This means we can leave out the description and by this indicate to our back end that the description should not be updated. Sounds good.

[3:22] What if we want to update description to null? No problem. We explicitly add the field and set it to null. This is great, but let's not get too excited about it because here comes the gotcha. We now only want to update the description.

[3:43] This means we have to remove the exclamation mark from name to make it optional. With this change, our schema now allows us to provide null for the name as well.

[3:56] Ugh. Name is a non-nullable property on the product model, but we just tried to update it to null. Our GraphQL server didn't complain. Why so? By making the name input field optional, we also made it nullable. Very unfortunate. I mean, not all hope is lost. We can check on the back end and throw an error when name is null. Let me quickly implement an example solver to demonstrate it.

[4:44] Now we run the query. Great. Now we see the GraphQL error. All in all, it's not as nice as it could be. That's the first tradeoff. We basically have to make non-nullable properties to be nullable input fields. Without additional documentation, this might add some confusion to your schema.

[5:05] The second potential issue is quite rare. We won't explore it in detail. What is it? In case there are some dependencies between input fields, you can't indicate that both have to be provided together using a flat input structure.

[5:21] In conclusion, an update mutation requires us to make tradeoffs, but in order to avoid ending up with hundreds of mutations the benefits might outweigh the disadvantages. In the end, that's for you and your team to decide.

egghead
egghead
~ 25 minutes ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today