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

I am trying to understand the more complex graphql apis that the Relay Cursor Connections Specification implements

If you look at the request below I have run 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
    } 
  }
}

      

Note that it has edge and node margins .

Why does github have an extra field called nodes in the api? Why don't they use the edge field, since you can get the same data from edges? Is it just for convenience?

+3


source to share


3 answers


If we look at the general structure of a generic connection implementation, you usually have the following: TypeA -> TypeAToTypeBConnection (usually a TypeA field with a type name typeBConnection

) -> TypeAToTypeBEdge (usually a name field when connecting with a name edges

) -> TypeB (usually a field name on a named edge node

))

A -> connection -> edges -> B

      

Connection types usually contain fields that contain information specific to the entire connection, which is usually paging information, total count, etc.

Border types usually have fields that have information specific to this connection, but not common to all nodes. The most common field in this case is cursor

which represents the location of the nodes in the connection, which is not a globally unique identifier, but a way to return to that location in the connection.

Node type is usually a type that is also associated with a connection, which does not contain any specific connection information

In the case of the githubs API, the Edge type has a normally implemented field cursor

that can later be used as a reference in that connection. They also have a field that traverses the type edge

in case you don't need cursors. This is why you see fields edges

and nodes

directly from the connection type.



To see these cursor fields, you can send the following request to see what I am talking about:

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

      

For more details on this connection style see here: https://facebook.github.io/relay/graphql/connections.htm

EDIT - Supplementary Answer: The purpose of providing access to both the edge type and the node type right at the junction can be at least two reasons I can think of. First, for the convenience of those using the API when using them does not require cursors. Second, there might be a case where, depending on the request sent, they might not even need to generate cursors. The second is likely to be minimal CPU time savings and is likely to be more trouble than it's worth.

Implementing cursors in a GraphQL endpoint in the past, once you get down to how, actually generating them isn't really that hard. It's just a matter of serializing a few key pieces of information. It may also be interesting to note that it is rather trivial to provide both ( A->conn->edge->B

and A->conn->B

) once you've created the Edge type.

Since I am not working for Github, I cannot tell you what the exact intent was. However, I would definitely think this is the first reason ... just for the convenience of the developers.

+5


source


A node is always the same no matter how you got to it. Edge is the metadata about that node in the context of the connection, usually just a cursor, but you can also add things like relevance score if your connection is a search term. This data shouldn't exist in the node itself, because it doesn't make sense in another context.

Terminology



  • Node is an object. In a circle diagram connected by lines, these would be circles.
  • Edge , connects two nodes together, may include metadata. These will be lines in the diagram.
  • Connection , paginated list of nodes. In the diagram, this will be a set of lines.
+4


source


This is probably just a convenience for them, as they probably have some crazy queries and this reduces object lookups in JavaScript. The edges will also contain a property cursor

, as well as a property node

that is probably not required everywhere, and hence another benefit of having a top-level margin node

.

It should also be noted that the boundary / course convention is heavily geared towards the particular relay environment, and furthermore, a cursor-based paging system where you can only navigate one index / page. If you want to create a more legacy swap system then you don't need to implement this type of paging.

The use case that breaks cursor-paging is that clients want to go to page 5 and are on page 1, which is not possible in Relay because cursors are opaque and are the basis for the "where" in the collection you are currently in.

Hope it helps!

+2


source







All Articles