Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutations for nested resources #221

Closed
xpepermint opened this issue Nov 5, 2015 · 6 comments

Comments

@xpepermint
Copy link

commented Nov 5, 2015

OK, mutations are queries for manipulating data. If so then my root query and root mutation tree should look similar and they both should allow nested fields (nested mutations). I was playing with this (using express-graphql) and it works.

Example:

// PUT /projects/:project_id/products/:id
mutation {
  findProject(id: 1) { // make sure that the project exists and we can access it before mutating data
    updateProduct(id: 1, name: "Foo") { // the resolve function receives a valid `project` as the first arg
      id
    }
  } 
}

Is this a valid example? Should mutations be nested like this? If no, how should I handle nested resources? I can not find any real-life example that would mutate nested resources. All examples define mutations only on the first level (fields on the root mutation).

@OlegIlyenko

This comment has been minimized.

Copy link
Contributor

commented Nov 12, 2015

There is at the moment one big difference between query and mutation type. Root mutation fields are guaranteed to execute strictly sequentially even if you are returning promises as a result of the resolve method. Root query fields, as well as nested mutation fields, do not have this execution guarantee.

So in other words only root mutation fields are meant to be used for mutations (at least I interpret it like this). I guess it depends on your use-case. So maybe it still make sense to do mutations in the nested fields as long as execution order does not matter.

In many cases though the order of execution matters. I think this GH issue raises a valid concern. Since sequential execution is limited only to root mutation fields, all possible application mutations should be defined as fields directly in the mutation type. In big applications and schemas it can cause very big mutation type with many unrelated/independent fields. Also I see namespacing as a problem. Given this flat mutation structure, I don't see other way but to follow naming convention to group related mutations together, which I find suboptimal in my case. That said, as long a number of mutation fields is low, I guess it should be manageable. Polymorphic input types can definitely help in this respect (at least in my case).

@leebyron

This comment has been minimized.

Copy link
Collaborator

commented Nov 17, 2015

We do not support mutations at any level other than the top. In cases where we need to support more complex mutations that rely on more information, we implement that in the resolve() function of the mutation.

In this case, updateProduct's resolve() function should first ensure that the product ID is valid before performing the update and do whatever is reasonable in the case that no product by that ID was found - perhaps return an error.

@leebyron leebyron closed this Nov 17, 2015

@xpepermint

This comment has been minimized.

Copy link
Author

commented Nov 17, 2015

@leebyron thanks!

@schickling

This comment has been minimized.

Copy link

commented Feb 17, 2017

Thanks for bringing this up @xpepermint.

We at Graphcool have written a blog post about nested mutations and how to use them to improve DX. You can find it here: https://www.graph.cool/blog/improving-dx-with-nested-mutations-vietahx7ih

The schema design we're proposing looks like this:

image

@prozacgod

This comment has been minimized.

Copy link

commented Mar 2, 2017

@schickling is createPost returning the 'post' type - the same as perhaps an expected query would return like getPost or a post object in the query.

If the result of createPost is the same type as the query of a post, could then the query of the author is independent of the results of the insert, as in I depending on implementation I could see where the author(data) in the result might not return the same author(data) as expected.

I totally understand why the graphql authors are being careful about their implementation, and some features that are requested, and the slowness of new features. This stuff hurts my head on a good day. AND it needs to be viable for many types of implementations.

@oney

This comment has been minimized.

Copy link

commented Dec 24, 2017

I believe my package is the best way to achieve nested mutations.
Check it out https://github.com/oney/graphql-mutate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants
You can’t perform that action at this time.