为什么Relay/GraphQL连接需要边缘?

Mic*_*hum 12 graphql relayjs

在Relay/GraphQL架构配置中,指定了一对多关系(带分页),如教程示例中所示

type ShipConnection {
  edges: [ShipEdge]
  pageInfo: PageInfo!
}
type ShipEdge {
  cursor: String!
  node: Ship
}
Run Code Online (Sandbox Code Playgroud)

但是,由一对一连接ShipEdge似乎是多余的.为什么我们不能将光标移动到ShipConnection并存储ShipID 数组作为边?

type ShipConnection {
  edges: [Ship]
  pageInfo: PageInfo!
  cursor: String!
}
Run Code Online (Sandbox Code Playgroud)

edge在一对多关系中,每个人需要一个额外对象的设计决策是什么?

Pet*_*ela 10

我能想到的边缘有两个原因:

  1. 它是边缘特定属性的地方.例如,如果你有一个User属于很多Groups的,那么在关系数据库中你有一个带user_id和的UserGroup表group_id.此表可以包含其他属性role,joined_at等等.GroupUserEdge然后,您可以访问这些属性.

  2. 有一个光标的地方.重要的一点是,连接中的每个节点都有一个游标(这就是为什么你不能在连接本身上只有一个游标).为什么我们(中继)需要每个节点都有一个游标?由于Relay智能地合并了整个应用程序的数据需求,因此它可能已经与您请求的相同参数建立了连接,但其中没有足够的记录.要获取丢失的数据,它可以在一些边缘光标之后请求连接中的数据.

    我理解这可能会令人困惑,因为数据库也有游标,并且每个查询只有一个游标.Relay连接实际上不是查询,而是一组标识查询的参数.连接边缘的光标是一组用于标识连接中位置的参数.这是一个比纯查询游标更高的抽象级别(请记住,边缘需要能够识别位置,即使在可能不是数据库查询的连接上,或者被第三方系统隐藏).由于这种所需的灵活性,连接的一个光标是不够的.

  • 我脑海中浮现出一个例子:您获取评论列表,但最后一条评论被删除。因此,要获取下一批注释,您需要从当前最后一个游标开始。我确定还有更多用例。关键是,Relay尝试尽可能通用并且足够健壮,以管理数据发生的任何事情。 (2认同)

win*_*ent 9

edges字段为您提供了放置每边数据的位置.例如,您可能希望在其上放置一个creatorpriority字段,分别描述添加边缘的人员以及关系的重要性.

如果您不需要这种灵活性(或者您通过连接获得的其他功能,例如分页),则可以使用简单GraphQLList类型.有关连接和列表之间差异的更多信息,请参阅此答案.


sch*_*ing 5

我们写了一篇关于简单GraphQL架构与Relay特定架构之间差异的博客文章:

https://blog.graph.cool/connections-edges-nodes-in-relay-758d358aa4c7