【问题标题】:GraphQL: How nested to make schema?GraphQL:如何嵌套创建模式?
【发布时间】:2019-05-25 19:52:01
【问题描述】:

去年我将一个应用程序转换为使用 Graphql。到目前为止它很棒,在转换过程中,我基本上移植了支持我的 REST 端点的所有服务,以支持 grapqhl 查询和突变。该应用程序运行良好,但希望继续改进我的对象图。

假设我有以下关系。

用户 -> 团队 -> 板 -> 列表 -> 卡片 -> 评论

我目前有两个不同的嵌套模式:用户 -> 团队:

    type User {
  id: ID!
  email: String!
  role: String!
  name: String!
  resetPasswordToken: String
  team: Team!
  lastActiveAt: Date
}

type Team {
  id: ID!
  inviteToken: String!
  owner: String!
  name: String!
  archived: Boolean!
  members: [String]
}

然后我有板 -> 列表 -> 卡片 -> 评论

type Board {
  id: ID!
  name: String!
  teamId: String!
  lists: [List]
  createdAt: Date
  updatedAt: Date
}

type List {
  id: ID!
  name: String!
  order: Int!
  description: String
  backgroundColor: String
  cardColor: String
  archived: Boolean
  boardId: String!
  ownerId: String!
  teamId: String!
  cards: [Card]
}

type Card {
  id: ID!
  text: String!
  order: Int
  groupCards: [Card]
  type: String
  backgroundColor: String
  votes: [String]
  boardId: String
  listId: String
  ownerId: String
  teamId: String!
  comments: [Comment]
  createdAt: Date
  updatedAt: Date
}

type Comment {
  id: ID!
  text: String!
  archived: Boolean
  boardId: String!
  ownerId: String
  teamId: String!
  cardId: String!
  createdAt: Date
  updatedAt: Date
}

效果很好。但我很好奇如何嵌套我才能真正制作我的架构。如果我添加其余部分以使图表完整:

type Team {
      id: ID!
      inviteToken: String!
      owner: String!
      name: String!
      archived: Boolean!
      members: [String]
      **boards: [Board]**
    }

这将获得更深的图表。但是我担心会有多少复杂的突变。特别是对于向下的板模式,我需要发布所有操作的订阅更新。如果我添加评论,发布整个董事会更新是非常低效的。虽然为每个嵌套模式的每次创建/更新都构建了订阅逻辑,但实现简单的事情似乎需要大量代码。

对对象图中的正确深度有什么想法吗?请记住,用户旁边的每个对象都需要广播给多个用户。

谢谢

【问题讨论】:

  • 谁在使用您的 API?听起来它是您也在开发的单个客户端。如果您知道哪些客户端或哪些客户端正在使用您的 API,那么这些客户端是否需要通过在 Team 类型上添加 boards 字段等提供的功能?
  • “如果我添加评论,发布整个董事会更新是非常低效的。”你能澄清一下为什么在添加评论时要发布整个董事会吗?我想添加评论只会导致发布到某种commentAdded 订阅。如果card 有一个comments 字段,客户端应该注意使用writeQuery 更新该字段,而不是依赖于发布的card。我错过了什么吗?

标签: node.js graphql apollo graphql-subscriptions


【解决方案1】:

GraphQL 的目的是避免几个查询,所以我确信制作嵌套结构是正确的方法。考虑到安全性,添加一些 GraphQL 深度限制库。

GraphQL style guides 建议您将所有复杂结构都放在单​​独的对象类型中(就像您拥有的那样,评论、团队、董事会...)。 然后进行复杂的查询/突变取决于您。

我想让你扩展这句话

如果我添加评论,发布整个董事会更新是 令人难以置信的低效

我不确定这一点,因为您有卡的 ID。因此,添加新评论将触发突变,这将创建新的评论记录并使用新评论更新卡片。

因此,您在后端的数据结构将定义您获取它的方式,而不是您改变它的方式。

GitHub GraphQL API为例:

  • 每个突变都是一个小函数,用于更新/创建复杂树的一部分,即使它们在后端有 nested structure 类型。

除了有关设计突变方法的一般知识外,我建议article

【讨论】:

  • 不完全确定为什么这没有更新我,抱歉延迟回复。您发布的关于 Modeling GraphQL Mutations 的文章非常值得一读。很有意义......我实际上只是发送一个 JSON 类型进行更新,因为我不想为每个字段编写一个突变。我想总结一下,对我来说最重要的感觉是订阅部分,我可以拥有这个惊人的可查询对象图,但需要为每个对象创建基本上 2 个订阅处理程序感觉很奇怪。也许一些框架会有所帮助,希望可以通过突变或其他东西的选项
【解决方案2】:

你可以在GraphQL中使用嵌套

type NestedObject {
  title: String
  content: String
}

type MainObject {
  id: ID!
  myObject: [NestedObject]
}

在上面的代码中,NestObject 的类型定义被注入到myObject 数组中。为了更好地理解,您可以将其视为:

type MainObject {
  id: ID!
  myobject: [
    {
      title: String
      content: String
    }
  ]
}

希望这能解决你的问题!

【讨论】:

    猜你喜欢
    • 2021-11-27
    • 2019-11-26
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    • 2018-09-19
    • 2018-07-23
    • 2018-04-06
    • 2017-01-06
    相关资源
    最近更新 更多