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

时间:2015-10-24 22:10:28

标签: graphql relayjs

在Relay / GraphQL架构配置中,一对多关系(带分页)指定为tutorial example

type ShipConnection {
  edges: [ShipEdge]
  pageInfo: PageInfo!
}
type ShipEdge {
  cursor: String!
  node: Ship
}

然而,ShipEdge所建立的一对一连接似乎是多余的。为什么我们不能将光标移动到ShipConnection并将Ship ID数组存储为边缘?

type ShipConnection {
  edges: [Ship]
  pageInfo: PageInfo!
  cursor: String!
}

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

3 个答案:

答案 0 :(得分:10)

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

  1. 这是特定于边缘的属性的位置。例如,如果您的User属于许多Group,则在关系数据库中,您将拥有一个包含user_idgroup_id的UserGroup表。此表格可以包含其他属性,例如rolejoined_at等。GroupUserEdge将成为您可以访问这些属性的位置。

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

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

答案 1 :(得分:9)

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

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

答案 2 :(得分:5)

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

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