嵌套资源上的 GraphQL 突变

Posted

技术标签:

【中文标题】嵌套资源上的 GraphQL 突变【英文标题】:GraphQL mutations on nested resources 【发布时间】:2016-02-07 11:07:05 【问题描述】:

突变是用于操作数据的查询。如果是这样,那么我的 root queryroot mutation 树应该看起来相似吧?它们都应该允许嵌套字段(嵌套突变)。我正在玩这个(使用express-graphql)并且它有效。

例子:

// PUT /projects/:project_id/products/:id
mutation 
  findProject(id: 1)  // make sure that 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 argument
      id
    
   

这是一个有效的例子吗?突变应该像这样嵌套吗?如果不是,我应该如何处理嵌套资源?我找不到任何会改变嵌套资源的真实示例。所有示例仅在第一级(根突变上的字段)上定义突变。

【问题讨论】:

我知道你在 GitHub 上得到了不支持它的答案,但我很好奇你是否真的放弃了这种方法,或者你是否坚持使用它,因为它似乎仍然有效。跨度> 也许你可以从 Graphcool 中的嵌套突变 api 中获得一些灵感:graph.cool/docs/reference/simple-api/… 【参考方案1】:

产品有一个唯一的 ID,因此您只需要识别它。

mutation 
  updateProduct(id: 1, name: "Foo") 
    id
  
 

要验证用户是否有权修改产品,您应该检查产品的项目。无论如何,您可能会有一些集中授权:

resolve( id ,  user ) 
  authorize(user, 'project', Product.find(id).project) // or whatever

  ... // update


旧答案:

这当然是一个有效的例子。

我猜缺少嵌套对象突变示例可能是因为即使产品链接到项目,在大多数情况下它仍然具有唯一 ID——因此您甚至可以找到该产品没有项目ID。

另一种选择是将项目 ID 作为参数包含在 updateProduct 中:

mutation 
  updateProduct(projectId: 1, id: 1, name: "Foo") 
    id
  
 

不过,您的解决方案对我来说似乎更好。


请注意,突变实际上与查询完全相同。唯一的区别是resolve 函数通常包含一些永久性更改,例如修改一些数据。尽管如此,突变的行为就像查询一样——验证参数,调用解析函数,返回声明类型的数据。

我们将这种方法声明为突变(而不是查询),以明确说明某些数据将被更改,但也有更重要的原因:修改数据的顺序很重要。如果您在一个请求中声明多个突变,执行器将按顺序运行它们以保持一致性(但这并没有尝试解决分布式写入,这完全是另一个问题)。

【讨论】:

嗯,GraphQL 的作者好像不同意github.com/graphql/graphql-js/issues/221 您的建议很危险。请记住,正如本文 (medium.com/the-graphqlhub/…) 中所指出的,查询和突变之间最重要的技术区别是“[...] 突变是串行处理的,但查询没有这样的保证”。

以上是关于嵌套资源上的 GraphQL 突变的主要内容,如果未能解决你的问题,请参考以下文章

带有嵌套突变的 Graphql?

GraphQL 嵌套突变 + Sequelize

graphql 突变不返回嵌套字段

突变中的 GraphQL 嵌套数据

编写嵌套的 GraphQL 突变

带有嵌套类型的 Graphql 突变?