Search code examples
graphqlrelayjsrelay

How to use (opaque) cursors in GraphQL / Relay when using filter arguments and order by


Imagine the following GraphQL request:

{
  books(
    first:10,
    filter: [{field: TITLE, contains: "Potter"}],
    orderBy: [{sort: PRICE, direction: DESC}, {sort: TITLE}]
  )
}

The result will return a connection with the Relay cursor information.

Should the cursor contain the filter and orderBy details?

Meaning querying the next set of data would only mean:

{
  books(first:10, after:"opaque-cursor")
}

Or should the filter and orderBy be repeated?

In the latter case the user can specify different filter and/or orderBy details which would make the opaque cursor invalid.

I can't find anything in the Relay spec about this.


Solution

  • I've seen this done multiple ways, but I've found that with cursor-based pagination, your cursor exists only within your dataset, and to change the filters would change the dataset, making it invalid.

    If you're using SQL (or something without cursor-based-pagination), then, you would need to include enough information in your cursor to be able to recover it. Your cursor would need to include all of your filter / order information, and you would need to disallow any additional filtering.

    You'd have to throw an error if they sent "after" along with "filter / orderBy". You could, optionally, check to see if the arguments are the same as the ones in your cursor, in case of user error, but there simply is no use-case to get "page 2" of a DIFFERENT set of data.