我可以向 GraphQL 边缘添加数据吗?

mar*_*eck 4 graphql

我在玩 GraphQL,并且遇到了连接和边缘的概念。

据我了解,在连接上看到元数据并不少见,例如totalCount以下代码段中的属性。

type UserFriendsConnection {
  pageInfo: PageInfo!
  edges: [UserFriendsEdge]
  totalCount: Int
}
Run Code Online (Sandbox Code Playgroud)

我的问题是是否可以将任意元数据也放在边缘,以及以下是否是一种体面的方式来做到这一点。

我觉得查询和回复最能说明我在寻找什么。这是role我想放置在有意义的地方的财产。

我觉得它不属于该User类型,因为该角色描述了UserGroup.

# Query

{
  me {
    id
    name
    groupsConnection {
      edges {
        node {
          id
          name
          membersConnection {
            edges {
                node {
                id
                name
              }
              role                             <--- HERE
            }
          }
        }
        role                                   <--- HERE
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)
# 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
          }
        ]
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*den 6

连接是Relay 规范的一部分。Relay 本身是一个 GraphQL 客户端,尽管您可以拥有一个兼容 Relay 的 GraphQL 服务器,而无需在前端实际使用 Relay。根据规范:

边类型必须具有名为 node 和 cursor 的字段。它们可能有与边缘相关的其他字段,因为模式设计者认为合适。

在这些类型上看到额外的字段是很常见的,这当然是有道理的。不过要提醒一句。如果我们有一个User类型,我们可以创建 aUserConnection和 a UserEdge

type UserConnection {
  pageInfo: PageInfo!
  egdes: [UserEdge!]!
}

type UserEdge {
  cursor: String!
  edge: User!
}
Run Code Online (Sandbox Code Playgroud)

然后我们可以在各种地方使用该连接类型......

type Query {
  allUsers: UserConnection!
  # other fields
}

type Group {
  members: UserConnection!
  # other fields
}

type User {
  coworkers: UserConnection!
  # other fields
}
Run Code Online (Sandbox Code Playgroud)

但是,如果添加像roleto 之类的字段UserEdge,则该字段仅membersGroup类型字段的上下文中才有意义。它必须在所有其他上下文中返回 null 或一些虚拟值,这可能会引入不必要的混淆。

这意味着,如果您要在关系相关的边缘类型上引入额外的字段,您可能应该创建特定于该关系的连接和边缘类型:

type GroupUserConnection {
  pageInfo: PageInfo!
  egdes: [GroupUserEdge!]!
}

type GroupUserEdge {
  cursor: String!
  edge: User!
  role: Role!
}
Run Code Online (Sandbox Code Playgroud)

这样,您仍然可以UserConnection对其他字段使用正则,并避免客户端不必要地请求一个没有的role地方。