You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: site/learn/BestPractice-Pagination.md
+6-2Lines changed: 6 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -54,7 +54,7 @@ There are a number of ways we could do pagination:
54
54
55
55
In general, we've found that **cursor-based pagination** is the most powerful of those designed. Especially if the cursors are opaque, either offset or ID-based pagination can be implemented using cursor-based pagination (by making the cursor the offset or the ID), and using cursors gives additional flexibility if the pagination model changes in the future. As a reminder that the cursors are opaque and that their format should not be relied upon, we suggest base64 encoding them.
56
56
57
-
That leads us to a problem; though; how do we get the cursor from the object? We wouldn't want cursor to live on the `User` type; it's a property of the connection, not of the object. So we want to introduce a new layer of indirection; our `friends` field should give us a list of edges, and an edge has both a cursor and the underlying node:
57
+
That leads us to a problem; though; how do we get the cursor from the object? We wouldn't want cursor to live on the `User` type; it's a property of the connection, not of the object. So we might want to introduce a new layer of indirection; our `friends` field should give us a list of edges, and an edge has both a cursor and the underlying node:
58
58
59
59
```graphql
60
60
{
@@ -92,13 +92,16 @@ To solve both of these problems, our `friends` field can return a connection obj
92
92
cursor
93
93
}
94
94
pageInfo {
95
+
endCursor
95
96
hasNextPage
96
97
}
97
98
}
98
99
}
99
100
}
100
101
```
101
102
103
+
Note that we also might include `endCursor` and `startCursor` in this `PageInfo` object. This way, if we don't need any of the additional information that the edge contains, we don't need to query for the edges at all, since we got the cursors needed for pagination from `pageInfo`. This leads to a potential usability improvement for connections; instead of just exposing the `edges` list, we could also expose a dedicated list of just the nodes, to avoid a layer of indirection.
104
+
102
105
## Complete Connection Model
103
106
104
107
Clearly, this is more complex than our original design of just having a plural! But by adopting this design, we've unlocked a number of capabilities for the client:
@@ -108,7 +111,7 @@ Clearly, this is more complex than our original design of just having a plural!
108
111
- The ability to ask for information about the edge itself, like `cursor` or `friendshipTime`.
109
112
- The ability to change how our backend does pagination, since the user just uses opaque cursors.
110
113
111
-
To see this in action, there's an additional field in the example schema, called `friendsConnection`, that exposes all of these concepts. You can check it out in the example query. Try removing the `after` parameter to `friendsConnection` to see how the pagination will be affected.
114
+
To see this in action, there's an additional field in the example schema, called `friendsConnection`, that exposes all of these concepts. You can check it out in the example query. Try removing the `after` parameter to `friendsConnection` to see how the pagination will be affected. Also, try replacing the `edges` field with the helper `friends` field on the connection, which lets you get directly to the list of friends without the additional edge layer of indirection, when that's appropriate for clients.
112
115
113
116
```graphql
114
117
# { "graphiql": true }
@@ -124,6 +127,7 @@ To see this in action, there's an additional field in the example schema, called
0 commit comments