Connection Concepts
Connections are a pagination solution which started with Relay JS, but now it’s used for almost any GraphQL API.
Connections are composed of a few kinds of objects:
-
Connectiontypes are generics that expose pagination-related metadata and access to the items -
Edgetypes are also generics. They represent the relationship between the parent and child (eg, aPostEdgerepresents the link fromBlogtoPost). -
nodes are actual list items. In a
PostsConnection, each node is aPost.
Connections have some advantages over offset-based pagination:
-
First-class support for relationship metadata
-
Cursor implementations can support efficient, stable pagination
Connections, Edges and Nodes
Connection pagination has three core objects: connections, edges, and nodes.
Nodes
Nodes are items in a list. A node is usually an object in your schema. For example, a node in a posts connection is a Post:
{
posts(first: 5) {
edges {
node {
# This is a `Post` object:
title
body
publishedAt
}
}
}
}
Connections
Connections are objects that represent a one-to-many relation. They contain metadata about the list of items and access to the items.
Connections are often generated from object types. Their list items, called nodes, are members of that object type. Connections can also be generated from union types and interface types.
Connection metadata
Connections can tell you about the list in general. For example, if you add a total count field, they can tell you the count:
{
posts {
# This is a PostsConnection
totalCount
}
}
Connection items
The list items in a connection are called nodes. They can generally be accessed two ways:
-
via edges:
posts { edges { node { ... } } } -
via nodes:
posts { nodes { ... } }
The differences is that edges { node { ... } } has more room for relationship metadata. For example, when listing the members of a team, you might include when someone joined the team as edge metadata:
team { members(first: 10) { edges { # when did this person join the team? joinedAt # information about the person: node { name } } } }
Alternatively, nodes provides easier access to the items, but can’t expose relationship metadata:
team { members(first: 10) { nodes { # shows the team members' names name } } }
There’s no way to show joinedAt above without using edges { ... }.
Edges
Edges are like join tables in that they can expose relationship metadata between a parent object and its children.
For example, let’s say that someone may be the member of several teams. You would make a join table in the database (eg, team_memberships) which connect people to each of the teams they’re on. This join table could also include information about how that person is related to the team: when they joined, what role they have, etc.
Edges can reveal this information about the relationship, for example:
team { # this is the team name name members(first: 10) { edges { # this is a team membership joinedAt role node { # this is the person on the team name } } } }
So, edges really help when the relationship between two objects has special data associated with it. If you use a join table, that’s a clue that you might use a custom edge to model the relationship.