apollo graphql 突变应该返回哪个值?

Posted

技术标签:

【中文标题】apollo graphql 突变应该返回哪个值?【英文标题】:Which value should be returned by a apollo graphql mutation? 【发布时间】:2021-04-25 00:36:54 【问题描述】:

我正在使用 apollo graphql 调用一些突变来更改数据库数据。我需要一些建议,通常应该返回哪个值。

对于insertOne(),我将返回新文档的 ID,对于删除数据集,我还将返回 ID,以删除客户端缓存中的数据集。

但是updateOne 呢?因为它可能是一个非常简单的任务,如下所示,但有时它可以进行一些复杂的更新?我不太确定哪个是最有用的返回值。

在这个简单的示例中,我只是更新了特定 mongodb 文档的一些内容。现在这个方法的 WriteResult 被返回了。但这真的有用吗?

我看到以下选项:

    返回 writeResult 对象 - 需要在后端定义 检查 writeResult 并返回布尔值,例如结果.nModified > 0 返回内容结果 - 最后将是输入内容 返回更新的文档 - 这需要findOne( _id: id ) 只是返回true,可能不是很有用?!

我知道没有适用于所有用例的单一解决方案,但也许有人可以解释一般情况下应该采用哪种方式......

服务器

async updateContent(id, name, value) 
  const Content = this.db.collection('content')
  return Content.updateOne(
     _id: id ,
     $set:  [name]: value  
  )

客户

updateContent(
  variables:  id, name, value 
)
  .then((response) => 
    // response.data.updateContent
  )
  .catch((error) => console.error(error))

graphql

mutation updateContent($id: ID!, $name: String, $value: String) 
  updateContent(id: $id, name: $name, value: $value) 
    nModified
  

架构

type WriteResult 
  nModified: Int,
  nRemoved: Int,
  nInserted: Int,
  n: Int
  ok: Int


type Mutation 
  updateContent(id: ID!, name: String, value: String): ContentString

【问题讨论】:

通常突变解析器返回...突变类型(但它是一个graphql,您不必查询所有字段/道具;响应将被过滤掉;返回数据=成功)...甚至删除的,惊喜! :D 【参考方案1】:

扩展之前的评论...

通常突变解析器返回...突变类型(但它是一个graphql,您不必查询所有字段/道具;响应将被过滤掉;返回数据=成功)...甚至删除的,惊喜! :D

返回变异对象类型对于更高级的 FE 技术可能很重要,例如 optimistic response。这可帮助您避免在更新一个元素时重新获取整个项目列表

在这种情况下

类型定义不正确 - 这是您的担忧

也许你应该把它定义得更像(输入类型更易于管理):

type ContentType 
  id: ID!
  content: String!
  author: User!
  createdAt: Date!
  updatedAt: Date!

type ContentCreateInputType 
  name: String!
  value: String!
     
type ContentUpdateInputType 
  id: ID!
  name: String!
  value: String!


type Stats 
  nModified: Int,
  nRemoved: Int,
  nInserted: Int,
  n: Int
  ok: Int
    
type ContentUpdatePayload 
  content: ContentType
  stats: Stats
    

type Mutation 
  updateContent(input: ContentUpdateInputType!): ContentUpdatePayload
    

这和流行的relay style cursor pagination有点相似。

你的突变可以是:

mutation updateContent($input: ContentUpdateInputType) 
  updateContent(input: $input) 
    stats 
      nModified
    
  

...在这种情况下,您的解析器必须只返回 stats 对象,不需要findOne ...但实际上它应该至少返回:

 
  content: 
    id
  
  stats: 
    nModified
    nRemoved
    // etc.
  

...因为您的突变也可以是:

mutation updateContent($input: ContentUpdateInputType) 
  updateContent(input: $input) 
    content 
      id
      content
      author 
        id
        name
      
    
    stats 
      nModified
    
  

返回 content: id stats: .... (js 对象,最小突变响应)对于解析整个查询是必要的(非常重要的)。服务器解析器将知道它尚未完成ContentType 对象(突变ContentUpdatePayload 元素),它将调用ContentType 解析器(以已知/已解析id 作为参数)来填充它(当然它会调用@987654333 @ 类型解析器)。

如您在上面注意到/看到的,只返回一个 content id (来自这个突变,ContentType 的一部分)可能是优化的一部分 - 没有过度获取 - 因为 id可以从突变参数中获取,并且仅在需要时才从数据库/服务中解析/读取整个内容。

结论

返回未输入的响应根本不允许这种“GraphQL 魔法”。

【讨论】:

以上是关于apollo graphql 突变应该返回哪个值?的主要内容,如果未能解决你的问题,请参考以下文章

返回突变结果的正确方法? (GraphQL 与 Apollo 和 Mongoose

React GraphQL 突变返回无效输入

在 Angular Apollo Graphql 中访问突变结果

来自 GraphQL 突变的动态响应

Apollo For GraphQL 不返回所需数据

Apollo GraphQL:未在突变子字段上调用解析器