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

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

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

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

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

我看到以下选项:

  1. 返回 writeResult 对象 - 需要在后端定义
  2. 检查 writeResult 并返回布尔值,例如结果.nModified > 0
  3. 返回内容结果 - 最后将是输入内容
  4. 返回更新的文档 - 这需要findOne({ _id: id })
  5. 只是返回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

标签: javascript mongodb graphql


【解决方案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 魔法”。

【讨论】:

    猜你喜欢
    • 2020-10-20
    • 2018-12-16
    • 2020-04-24
    • 2019-11-27
    • 2018-10-17
    • 2021-08-22
    • 2019-01-08
    • 2017-02-07
    • 2019-11-25
    相关资源
    最近更新 更多