在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
需要一个额外对象的设计决策是什么?
答案 0 :(得分:10)
我能想到的边缘有两个原因:
这是特定于边缘的属性的位置。例如,如果您的User
属于许多Group
,则在关系数据库中,您将拥有一个包含user_id
和group_id
的UserGroup表。此表格可以包含其他属性,例如role
,joined_at
等。GroupUserEdge
将成为您可以访问这些属性的位置。
有光标的位置。重要的一点是,连接中的每个节点都有一个游标(这就是为什么你不能在连接本身上只有一个游标)。为什么我们(中继)需要每个节点都有一个游标?由于Relay智能地合并了整个应用程序的数据需求,因此它可能已经与您请求的相同参数建立了连接,但其中没有足够的记录。要获取丢失的数据,它可以在一些边缘光标后请求连接中的数据。
我理解这可能会令人困惑,因为数据库也有游标,并且每个查询只有一个游标。 Relay连接实际上不是查询,而是一组标识查询的参数。连接边缘的光标是一组用于标识连接中位置的参数。这是一个比纯查询游标更高的抽象级别(请记住,边缘需要能够识别位置,即使在可能不是数据库查询的连接上,或者被第三方系统隐藏)。由于这种所需的灵活性,连接的一个光标是不够的。
答案 1 :(得分:9)
edges
字段为您提供了放置每边数据的位置。例如,您可能希望在其上放置creator
或priority
字段,分别描述添加边缘的人员以及关系的重要性。
如果您不需要这种灵活性(或者您通过连接获得的其他功能,例如分页),则可以使用简单的GraphQLList
类型。有关连接和列表之间差异的更多信息,请参阅this answer。
答案 2 :(得分:5)
我们撰写了一篇关于简单GraphQL架构与中继特定架构之间差异的博客文章:
https://blog.graph.cool/connections-edges-nodes-in-relay-758d358aa4c7