【问题标题】:Can I add data to a GraphQL edge?我可以将数据添加到 GraphQL 边缘吗?
【发布时间】:2019-03-02 00:28:22
【问题描述】:

我正在使用 GraphQL,并且遇到过连接和边的概念。

据我了解,在连接上看到元数据并不少见,例如以下 sn-p 中的 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
          }
        ]
      }
    }
  }
}

【问题讨论】:

    标签: graphql


    【解决方案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,则该字段仅在 Group 类型的 members 字段的上下文中才有意义。它必须在所有其他上下文中返回 null 或一些虚拟值,这可能会引起不必要的混淆。

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

    type GroupUserConnection {
      pageInfo: PageInfo!
      egdes: [GroupUserEdge!]!
    }
    
    type GroupUserEdge {
      cursor: String!
      edge: User!
      role: Role!
    }
    

    这样,您仍然可以将常规UserConnection 用于其他字段,并避免客户端在没有role 的情况下不必要地请求。

    【讨论】:

    • 太棒了!非常感谢您为我澄清这一点。我计划拥有单独的连接类型,以确保依赖关系的东西只存在于有意义的地方。所以,感谢您也添加这部分答案。
    猜你喜欢
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    相关资源
    最近更新 更多