我正在玩GraphQL,并且遇到了连接和边的概念。
据我了解,在连接上看到元数据并不罕见,例如以下代码段中的totalCount
属性。
type UserFriendsConnection {
pageInfo: PageInfo!
edges: [UserFriendsEdge]
totalCount: Int
}
我的问题是,是否还可以将任意元数据放在边缘,是否可以通过以下方式做到这一点?
我觉得查询和响应可以最好地说明我在寻找什么。我想将role
属性放在有意义的位置。
我觉得它不属于User
类型,因为角色描述了User
与Group
的连接/关系类型。
# Query
{
me {
id
name
groupsConnection {
edges {
node {
id
name
membersConnection {
edges {
node {
id
name
}
role <--- HERE
}
}
}
role <--- HERE
}
}
}
}
# Response
{
"data": {
"me": {
"id": "1Edj3hZFg",
"name": "John Doe",
"groupsConnection": {
"edges": [
{
"node": {
"id": "bpQgdZweQE",
"name": "Fishing Team",
"membersConnection": {
"edges": [
{
"node": {
"id": "1Edj3hZFg",
"name": "John Doe"
},
"role": "ADMINISTRATOR" <--- HERE
},
{
"node": {
"id": "7dj37dH2d",
"name": "Rebecca Anderson"
},
"role": "MEMBER" <--- HERE
}
]
}
},
"role": "ADMINISTRATOR" <--- HERE
}
]
}
}
}
}
答案 0 :(得分:1)
连接是Relay specification的一部分。 Relay本身是GraphQL客户端,尽管您可以拥有一个与Relay兼容的GraphQL服务器,而无需在前端实际使用Relay。根据规格:
边缘类型必须具有名为node和cursor的字段。正如架构设计人员认为合适的那样,它们可能具有与边缘相关的其他字段。
看到这些类型的其他字段很常见,这当然是有道理的。不过要小心一点。如果我们使用User
类型,则可以创建一个UserConnection
和一个UserEdge
:
type UserConnection {
pageInfo: PageInfo!
egdes: [UserEdge!]!
}
type UserEdge {
cursor: String!
edge: User!
}
然后我们可以在各种地方使用该连接类型...
type Query {
allUsers: UserConnection!
# other fields
}
type Group {
members: UserConnection!
# other fields
}
type User {
coworkers: UserConnection!
# other fields
}
但是,如果将role
之类的字段添加到UserEdge
,则该字段仅在members
类型的Group
字段的上下文中才有意义。在所有其他情况下,它必须返回null或一些虚拟值,这可能会引起不必要的混乱。
这意味着,如果要在边缘类型上引入依赖于关系的其他字段,则可能应该创建特定于该关系的连接和边缘类型:
type GroupUserConnection {
pageInfo: PageInfo!
egdes: [GroupUserEdge!]!
}
type GroupUserEdge {
cursor: String!
edge: User!
role: Role!
}
通过这种方式,您仍然可以将常规UserConnection
用于其他字段,并避免客户端不必要地请求role
。