Skip to main content
The Pylon GraphQL API uses cursor-based pagination for collections. This guide shows you how to page through results using the connection pattern.

Understanding connections

Connections are collections that support pagination. They follow a consistent structure:
query {
  deals(first: 10) {
    edges {
      node {
        id
        status
      }
    }
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
  }
}

Connection fields

  • edges: An array of edge objects, each containing a node and a cursor
  • node: The actual data object
  • pageInfo: Information about the current page and available pages
    • hasNextPage: Boolean indicating if more pages are available
    • hasPreviousPage: Boolean indicating if previous pages exist
    • startCursor: Cursor for the first item in the current page
    • endCursor: Cursor for the last item in the current page

Forward pagination

Use first and after to page forward:
query GetDeals($first: Int, $after: String) {
  deals(first: $first, after: $after) {
    edges {
      node {
        id
        status
      }
      cursor
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
Variables for first page:
{
  "first": 10
}
Variables for next page:
{
  "first": 10,
  "after": "eyJpZCI6IjEyMyJ9"
}

Backward pagination

Use last and before to page backward:
query GetDeals($last: Int, $before: String) {
  deals(last: $last, before: $before) {
    edges {
      node {
        id
        status
      }
      cursor
    }
    pageInfo {
      hasPreviousPage
      startCursor
    }
  }
}

Pagination limits

  • first and last must be between 1 and 500
  • You must specify either first or last, but not both
  • If you specify first, you can optionally include after
  • If you specify last, you can optionally include before

Example: paginating through all deals

async function getAllDeals(accessToken) {
  let allDeals = [];
  let hasNextPage = true;
  let cursor = null;

  while (hasNextPage) {
    const query = `
      query GetDeals($first: Int, $after: String) {
        deals(first: $first, after: $after) {
          edges {
            node {
              id
              status
            }
          }
          pageInfo {
            hasNextPage
            endCursor
          }
        }
      }
    `;

    const variables = {
      first: 100,
      ...(cursor && { after: cursor })
    };

    const response = await fetch('https://pylon.mortgage/graphql', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ query, variables })
    });

    const result = await response.json();
    const deals = result.data.deals;

    allDeals = allDeals.concat(deals.edges.map(edge => edge.node));
    hasNextPage = deals.pageInfo.hasNextPage;
    cursor = deals.pageInfo.endCursor;
  }

  return allDeals;
}

Filtering with pagination

You can combine pagination with filters:
query GetDeals($first: Int, $after: String, $status: DealStatus) {
  deals(first: $first, after: $after, status: $status) {
    edges {
      node {
        id
        status
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Best practices

  1. Use appropriate page sizes - Don’t request more than you need, but avoid too many small requests
  2. Store cursors - Save endCursor to resume pagination later
  3. Handle empty results - Check if edges is empty
  4. Respect rate limits - Don’t make excessive pagination requests
  5. Use hasNextPage - Check this before making another request

Common patterns

Fetching a specific page

If you need to jump to a specific page, you’ll need to paginate from the beginning or store cursors:
async function getPage(accessToken, pageNumber, pageSize = 10) {
  let currentPage = 0;
  let cursor = null;

  while (currentPage < pageNumber) {
    const result = await fetchPage(accessToken, pageSize, cursor);
    cursor = result.pageInfo.endCursor;
    currentPage++;
  }

  return result;
}

Counting total items

The connection pattern doesn’t provide a total count. If you need a count, you’ll need to paginate through all items or use a separate query if available.