在您的 graphql 模式中连接边和节点的原因是什么?

What is the reason for having edges and nodes in a connection in your graphql schema?

我正在尝试了解实现 Relay Cursor Connections Specification

的更复杂的 graphql api

如果您查看下面的查询,我 运行 在 github graphql api explorer

{
  repository(owner: "getsmarter", name: "moodle-api") {
    id
    issues(first:2 ) {
      edges {
        node {
          id
          body
        }
      }
      nodes {
        body
      }
      pageInfo {
        endCursor
        hasNextPage
        hasPreviousPage
        startCursor
      }
      totalCount
    } 
  }
}

注意它有字段 edgesnodes.

为什么 github 在其 api 中有一个名为节点的附加字段?为什么他们不直接使用边缘字段,因为你可以从边缘获得相同的数据?这只是为了方便吗?

这对他们来说可能只是一种方便,因为他们可能有一些疯狂的查询,并且它减少了 object 在 JavaScript 中的查找。边也将包含 cursor 属性 以及 node 属性,它们可能不需要任何地方,因此具有 [=24= 的另一个好处] node 字段。

我还应该注意到 edge/cursor 约定非常适合中继特定环境,此外还有一个 cursor-based 寻呼系统,您只能移动一个 index/page。如果你的愿望是创建一个更legacy-based的分页系统,那么你不必实现这种类型的分页。

A use-case break cursor-paging 是如果客户端想跳转到第 5 页,并且在第 1 页,这在 Relay 中是不可能的,因为游标是不透明的,并且是基础"where" 在 collection 你目前在。

希望对您有所帮助!

无论您如何到达节点,节点始终是相同的。边缘是关于连接上下文中该节点的元数据,通常只是光标,但如果您的连接代表搜索查询,您也可以添加诸如相关性分数之类的东西。此数据不应存在于节点本身,因为它在不同的上下文中没有意义。

术语:

  1. 节点,表示一个实体。在由线连接的圆圈图中,这些就是圆圈。
  2. Edge,将两个节点连接在一起,可能包含元数据。在图中,这些就是线。
  3. Connection,节点的分页列表。在图中,这将是线条的集合。

如果我们查看通用连接实现的一般结构,您通常具有以下内容: TypeA -> TypeAToTypeBConnection(通常是 TypeA 上的字段,名称如 typeBConnection) -> TypeAToTypeBEdge(通常是名称 edges 连接上的名称字段) -> TypeB(通常是边上的字段名称,名称是node)

A -> connection -> edges -> B

连接类型 通常会有包含特定于整个连接的信息的字段,通常是分页信息、总计数等。

边缘类型通常有一些字段,这些字段包含特定于该连接但并非所有节点都通用的信息。在这种情况下,最常见的字段是 cursor,它表示连接中的节点“位置”,它不是全局唯一 ID,而是 return 到连接中该位置的一种方式。

节点类型通常只是连接的类型,不包含连接特定信息

在 github 的 API 情况下,Edge 类型具有通常实现的 cursor 字段,以后可以在该连接中用作参考。如果您不需要游标,它们还有一个绕过 edge 类型的字段。这就是为什么您会直接在连接类型之外看到 edgesnodes 字段。

要查看这些游标字段,您可以发送以下查询以查看我在说什么:

{
  repository(owner: "getsmarter", name: "moodle-api") {
    issues(first:2 ) {
      edges {
        cursor
        node {
          id
        }
      }
    }
  }
}

有关这种连接方式的更多详细信息,请查看此处:https://facebook.github.io/relay/graphql/connections.htm

编辑 - 附加回复: 允许在连接处同时访问边类型和节点类型的目的至少有两个我能想到的原因。首先,为了方便那些在用例不需要游标时使用 API 的人。其次,在某些情况下,根据发送的查询,他们可能甚至不需要生成游标。第二个可能会在 CPU 时间上节省最少的时间,而且可能比它值得的麻烦更多。

我自己过去曾在 GraphQL 端点中实现过游标,一旦了解了方法,实际生成游标并不是那么困难。这只是序列化一些关键信息的问题。还可能值得注意的是,一旦您已经创建了 Edge 类型,同时提供 (A->conn->edge->BA->conn->B) 是非常简单的。

因为我不为 Github 工作,所以我不能告诉你确切的意图。但是,我绝对认为这是第一个原因……只是为了方便开发人员。