DEV Community

Brett Jephson
Brett Jephson

Posted on

Designing Graphql Schemas: Connections

As part of my learning in public drive for the new year, I thought I'd write down some notes as I take in Nik Graf's course on Designing GraphQL Schemas.

This will be a series of short posts based on my notes. I'm continuing here with some notes on pagination and connections.


Limiting the amount of data returned is best done by following the connections spec defined for Relay and now widely used by other (non-Relay) GraphQL solutions.

This means pagination is represented by a cursor-based connection, which looks something like this:

  item(first: 10, after: "aCursor") {
    edges {
      node {
    pageInfo {

In the example, item would return an ItemConnection. It would accept arguments for first, which is an integer limiting the number of results returned and analogous to limit in many pagination systems, and after, which is an opaque cursor.


The first time I heard the words "opaque cursor" it sounded obscure and a bit complicated.

A cursor is essentially something unique that points to a data item. This level of abstraction means you can store different information in a cursor and find slices of data in different ways. It might be that you need to slice the data by timestamp in one instance and by id in another. Or by some legacy information to adapt your existing rest api. A cursor allows for any of these options.

These cursors are opaque because we normally encode them using base64 to make the data opaque. For example, we don't need to know that the cursor is defined from an id and a timestamp, we just need to know that it is a unique pointer to the data we are interested in.

Take a look at the connection spec if you would like more of an explanation.


The data is returned as an array of edge objects, which includes the cursor for the item and a node, which is the data item itself.


As well as the set of edges, a connection also includes a page information object, with the start and end cursors for the particular page and boolean values for whether there is a next or previous page.

The page information object is flexible and can be extended as needed, depending on the pagination needs for the data you are querying. This might include data filtering, for example.

Top comments (0)