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

时间:2019-03-01 15:40:41

标签: graphql

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

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

type UserFriendsConnection {
  pageInfo: PageInfo!
  edges: [UserFriendsEdge]
  totalCount: Int
}

我的问题是,是否还可以将任意元数据放在边缘,是否可以通过以下方式做到这一点?

我觉得查询和响应可以最好地说明我在寻找什么。我想将role属性放在有意义的位置。

我觉得它不属于User类型,因为角色描述了UserGroup的连接/关系类型。

# 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
          }
        ]
      }
    }
  }
}

1 个答案:

答案 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