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: docs/source/tutorial/resolvers.md
+127-2Lines changed: 127 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -143,11 +143,136 @@ A response like this should be returned at the right side of the playground.
143
143
144
144

145
145
146
+
<h2id="pagination">Pagination</h2>
147
+
148
+
The `launches` query returned a large data set of launches. This data set contains too much data to be fetched all at once.
149
+
150
+
Pagination is a solution to the challenge of fetching all the data at once. It's a technique that ensures that the server only sends data in small chunks per time. There are two major ways of fetching paginated data: offset-based (otherwise known as numbered pages), and cursor-based pagination.
151
+
152
+
Cursor-based pagination is the more efficient way of fetching paginated data because it eliminates the possibility of skipping items and displaying the same item more than once. In cursor-based pagination, a constant pointer is used to keep track of where in the data set the next items should be fetched from. This pointer is called a **cursor**.
153
+
154
+
We'll use a cursor-based pagination for our graph API. This approach requires two parameters:
155
+
156
+
* The number of items to fetch at once.
157
+
* The cursor.
158
+
159
+
Open up the `src/schema.js` file and update the `Query` type. Go ahead and add a new type called `LaunchConnection` to the schema as shown below:
160
+
161
+
_src/schema.js_
162
+
163
+
```js
164
+
type Query {
165
+
launches(
166
+
"""
167
+
The number of results to show. Must be >= 1. Default = 20
168
+
"""
169
+
pageSize: Int
170
+
"""
171
+
If you add a cursor here, it will only return results _after_ this cursor
172
+
"""
173
+
after:String
174
+
): LaunchConnection!
175
+
launch(id:ID!): Launch
176
+
me: User
177
+
}
178
+
179
+
"""
180
+
Simple wrapper around our list of launches that contains a cursor to the
181
+
last item in the list. Pass this cursor to the launches query to fetch results
182
+
after these.
183
+
"""
184
+
type LaunchConnection {
185
+
cursor:String!
186
+
hasMore:Boolean!
187
+
launches: [Launch]!
188
+
}
189
+
...
190
+
```
191
+
192
+
The `launches` field takes in two parameters, `pageSize` and `after`. `pageSize` refers to the number of items to show at once while `after` refers to the cursor that keeps track of where the next set of data should be fetched from. We created a `LaunchConnection` type that returns a result that shows the list of launches with a `cursor` field and a `hasMore` field to indicate if there's more data to be fetched.
193
+
194
+
Copy the pagination helper code below and paste it in the `src/utils.js` file.
195
+
196
+
_src/utils.js_
197
+
198
+
```js
199
+
module.exports.paginateResults= ({
200
+
after: cursor,
201
+
pageSize =20,
202
+
results,
203
+
// can pass in a function to calculate an item's cursor
204
+
getCursor= () =>null,
205
+
}) => {
206
+
if (pageSize <1) return [];
207
+
if (!cursor) returnresults.slice(0, pageSize);
208
+
209
+
constcursorIndex=results.findIndex(item=> {
210
+
// if an item has a `cursor` on it, use that, otherwise try to generate one
211
+
let itemCursor =item.cursor?item.cursor:getCursor(item);
212
+
// if there's still not a cursor, return false by default
213
+
return itemCursor ? cursor === itemCursor :false;
214
+
});
215
+
216
+
return cursorIndex >=0
217
+
? cursorIndex ===results.length-1// don't let us overflow
The code above is a helper function for paginating data from the server.Now, let's update the necessary resolver functions to accomodate pagination.
229
+
230
+
First, copy the code below and add it to the top of the `src/resolvers.js` file.
231
+
232
+
```js
233
+
const { paginateResults } =require('./utils');
234
+
```
235
+
236
+
We required the `paginateResults` function from the `src/utils.js` file. Now, update the `launches` resolver function in the `src/resolvers.js` file with the code below:
// if the cursor of the end of the paginated results is the same as the
255
+
// last item in _all_ results, then there are no more results after this
256
+
hasMore:launches.length
257
+
? launches[launches.length-1].cursor!==
258
+
allLaunches[allLaunches.length-1].cursor
259
+
:false,
260
+
};
261
+
},
262
+
...
263
+
```
264
+
265
+
Let's test the cursor-based pagination we just implemented. Go ahead and run your GraphQL server, write a `launches` query in GraphQL Playground and pass a `pageSize` value of 3.
266
+
267
+
The response should look like the paginated data shown below:
Authentication is a common part of every application. There are several ways to handle authentication and authorization.
273
+
Authentication is a common part of every application. There are several ways to [handle authentication and authorization in your graph API](https://www.apollographql.com/docs/guides/access-control.html).
149
274
150
-
In this tutorial, we use a login token in an HTTP authorization header.
275
+
In this tutorial, we use a login token in an HTTP authorization header and put user info on the `context`.
151
276
152
277
Update the `context` section of the `ApolloServer` constructor in `src/index.js` to have the code shown below:
0 commit comments