You are viewing documentation for a preview version of this software.

Learn about previews.

Relay-style pagination


Relay-style pagination is a common way of modeling pagination in GraphQL, where fields return Connections that contain a list of Edges:

GraphQL
1type Query {
2  usersConnection(first: Int = 10, after: String = null, last: Int = null, before: String = null): UserConnection!
3}
4
5type UserConnection {
6  pageInfo: PageInfo!
7  edges: [UserEdge!]!
8}
9
10type PageInfo {
11  hasNextPage: Boolean!
12  hasPreviousPage: Boolean!
13  startCursor: String
14  endCursor: String
15}
16
17type UserEdge {
18  cursor: String!
19  node: User!
20}
21
22type User {
23  id: ID!
24  name: String!
25}
GraphQL
1query UsersConnection($first: Int, $after: String, $last: Int, $before: String) {
2  usersConnection(first: $first, after: $after, last: $last, before: $before) {
3    edges {
4      cursor
5      node {
6        name
7      }
8    }
9    pageInfo {
10      hasNextPage
11      endCursor
12    }
13  }
14}

If your schema uses this pagination style, the library supports it out of the box: use the @connection directive on Connection types:

GraphQL
1# First import the directive
2extend schema @link(
3  url: "https://specs.apollo.dev/cache/v0.4",
4  import: ["@connection"]
5)
6
7# Then extend your types
8extend type UserConnection @connection

In Kotlin, configure the cache like this, using the generated cache() function:

Kotlin
1val client = ApolloClient.Builder()
2  // ...
3  .cache(cacheFactory)
4  .build()

Query UsersConnection() to fetch new pages and update the cache, and watch it to observe the full list.

Caveats

For the cache to be able to merge pages correctly, the node field of the XyzEdge types must return an object with a unique identifier, i.e. it must have its key fields configured with @typePolicy.

Sample

A sample project using this type of pagination is available here.

Feedback

Edit on GitHub

Ask Community