GraphQL pagination

All of our GraphQL query endpoints that support pagination use cursor-based pagination, implementing a pattern formalized by the GraphQL Relay team. Here is a nice overview of the approach and rationale:

https://graphql.org/learn/pagination/#pagination-and-edges

As an example, you can use your API key to try out our SearchCustomers example in our Postman collection:
Postman Collection: Endear Customers and Messaging

We start by making a request consisting of this query:

query SearchCustomers($first: Int, $after: String, $sortBy: SortCustomersBy, $sortDir: SortDirection, $search: String) {
  searchCustomers(first: $first, after: $after, sortBy: $sortBy, sortDir: $sortDir, search: $search) {
    edges {
      node {
        id
        first_name
      }
      cursor
    }
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
  }
}

and these variables:

{
  "first": 2,
  "after": null,
  "sortBy": "UPDATED_AT",
  "sortDir": "ASC",
  "search": null
}

We're fetching the first two customer ids from our account, sorted by the date they were updated. We receive a response like this, containing the oldest updated customers, Rebecca and Gabe:

{
  "data": {
    "searchCustomers": {
      "edges": [
        {
          "node": {
            "id": "customer-id-1",
            "first_name": "Rebecca"
          },
          "cursor": "cursor-1-abcd"
        },
        {
          "node": {
            "id": "customer-id-2",
            "first_name": "Gabe"
          },
          "cursor": "cursor-2-efjh"
        }
      ],
      "pageInfo": {
        "hasNextPage": true,
        "hasPreviousPage": false,
        "startCursor": "cursor-1-abcd",
        "endCursor": "cursor-2-efjh"
      }
    }
  }
}

Note that each customer node is returned alongside a cursor. The last customer in the list has its cursor included in the pageInfo.endCursor field, and pageInfo.hasNextPage is true, indicating there are more results to be fetched beyond those first two. Now we can send the same query, but using that endCursor in the after argument of our variables:

{
  "first": 2,
  "after": "cursor-2-efjh",
  "sortBy": "UPDATED_AT",
  "sortDir": "ASC",
  "search": null
}

This returns the next two customers, Theresa and Nikki:

{
  "data": {
    "searchCustomers": {
      "edges": [
        {
          "node": {
            "id": "customer-id-3",
            "first_name": "Theresa"
          },
          "cursor": "cursor-3-ijkl"
        },
        {
          "node": {
            "id": "customer-id-4",
            "first_name": "Nikki"
          },
          "cursor": "cursor-4-mnop"
        }
      ],
      "pageInfo": {
        "hasNextPage": true,
        "hasPreviousPage": true,
        "startCursor": "cursor-3-ijkl",
        "endCursor": "cursor-4-mnop"
      }
    }
  }
}

Having issues? Some key detail missing from this guide? Let us know!