Pagination

Pagination

Overview

The Finale GraphQL API uses cursor-based pagination following the Relay connection specification. This provides efficient navigation through large datasets.

Pagination Arguments

All ViewConnection queries support these arguments:

PageInfo Object

Every ViewConnection returns a pageInfo object with:

pageInfo {
  hasNextPage      # Boolean: Are there more items after this page?
  hasPreviousPage  # Boolean: Are there items before this page?
  startCursor      # String: Cursor for first item in results
  endCursor        # String: Cursor for last item in results
}

Forward Pagination Pattern

To paginate forward through results:

# Page 1
query {
  orderViewConnection(first: 50) {
    edges {
      node {
        orderId
        orderDate
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

# Page 2 - Use endCursor from previous page
query {
  orderViewConnection(first: 50, after: "cursor-value-from-page-1") {
    edges {
      node {
        orderId
        orderDate
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Backward Pagination Pattern

To paginate backward:

query {
  orderViewConnection(last: 50, before: "cursor-value") {
    edges {
      node {
        orderId
        orderDate
      }
    }
    pageInfo {
      hasPreviousPage
      startCursor
    }
  }
}

Cursor Format

Cursors are opaque strings that encode pagination position. They are:

Example cursor value:eyJpZHgiOjEwfQ==

Best Practices

  1. Always check hasNextPage before requesting more pages
  2. Store cursors from pageInfo to navigate between pages
  3. Use consistent page size for predictable performance
  4. Don't decode cursors - treat them as opaque strings
  5. Combine with sorting for predictable pagination order

Complete Example

query GetProducts($cursor: String) {
  productViewConnection(
    first: 100
    after: $cursor
    sort: [{ field: "productId", mode: "asc" }]
  ) {
    edges {
      node {
        productId
        sku
        description
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}