monday_ruby 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.env +1 -1
- data/.rspec +0 -1
- data/.rubocop.yml +19 -0
- data/.simplecov +1 -0
- data/CHANGELOG.md +49 -0
- data/CONTRIBUTING.md +165 -0
- data/README.md +167 -88
- data/docs/.vitepress/config.mjs +255 -0
- data/docs/.vitepress/theme/index.js +4 -0
- data/docs/.vitepress/theme/style.css +43 -0
- data/docs/README.md +80 -0
- data/docs/explanation/architecture.md +507 -0
- data/docs/explanation/best-practices/errors.md +478 -0
- data/docs/explanation/best-practices/performance.md +1084 -0
- data/docs/explanation/best-practices/rate-limiting.md +630 -0
- data/docs/explanation/best-practices/testing.md +820 -0
- data/docs/explanation/column-values.md +857 -0
- data/docs/explanation/design.md +795 -0
- data/docs/explanation/graphql.md +356 -0
- data/docs/explanation/migration/v1.md +808 -0
- data/docs/explanation/pagination.md +447 -0
- data/docs/guides/advanced/batch.md +1274 -0
- data/docs/guides/advanced/complex-queries.md +1114 -0
- data/docs/guides/advanced/errors.md +818 -0
- data/docs/guides/advanced/pagination.md +934 -0
- data/docs/guides/advanced/rate-limiting.md +981 -0
- data/docs/guides/authentication.md +286 -0
- data/docs/guides/boards/create.md +386 -0
- data/docs/guides/boards/delete.md +405 -0
- data/docs/guides/boards/duplicate.md +511 -0
- data/docs/guides/boards/query.md +530 -0
- data/docs/guides/boards/update.md +453 -0
- data/docs/guides/columns/create.md +452 -0
- data/docs/guides/columns/metadata.md +492 -0
- data/docs/guides/columns/query.md +455 -0
- data/docs/guides/columns/update-multiple.md +459 -0
- data/docs/guides/columns/update-values.md +509 -0
- data/docs/guides/files/add-to-column.md +40 -0
- data/docs/guides/files/add-to-update.md +37 -0
- data/docs/guides/files/clear-column.md +33 -0
- data/docs/guides/first-request.md +285 -0
- data/docs/guides/folders/manage.md +750 -0
- data/docs/guides/groups/items.md +626 -0
- data/docs/guides/groups/manage.md +501 -0
- data/docs/guides/installation.md +169 -0
- data/docs/guides/items/create.md +493 -0
- data/docs/guides/items/delete.md +514 -0
- data/docs/guides/items/query.md +605 -0
- data/docs/guides/items/subitems.md +483 -0
- data/docs/guides/items/update.md +699 -0
- data/docs/guides/updates/manage.md +619 -0
- data/docs/guides/use-cases/dashboard.md +1421 -0
- data/docs/guides/use-cases/import.md +1962 -0
- data/docs/guides/use-cases/task-management.md +1381 -0
- data/docs/guides/workspaces/manage.md +502 -0
- data/docs/index.md +69 -0
- data/docs/package-lock.json +2468 -0
- data/docs/package.json +13 -0
- data/docs/reference/client.md +540 -0
- data/docs/reference/configuration.md +586 -0
- data/docs/reference/errors.md +693 -0
- data/docs/reference/resources/account.md +208 -0
- data/docs/reference/resources/activity-log.md +369 -0
- data/docs/reference/resources/board-view.md +359 -0
- data/docs/reference/resources/board.md +393 -0
- data/docs/reference/resources/column.md +543 -0
- data/docs/reference/resources/file.md +236 -0
- data/docs/reference/resources/folder.md +386 -0
- data/docs/reference/resources/group.md +507 -0
- data/docs/reference/resources/item.md +348 -0
- data/docs/reference/resources/subitem.md +267 -0
- data/docs/reference/resources/update.md +259 -0
- data/docs/reference/resources/workspace.md +213 -0
- data/docs/reference/response.md +560 -0
- data/docs/tutorial/first-integration.md +713 -0
- data/lib/monday/client.rb +41 -2
- data/lib/monday/configuration.rb +13 -0
- data/lib/monday/deprecation.rb +23 -0
- data/lib/monday/error.rb +5 -2
- data/lib/monday/request.rb +19 -1
- data/lib/monday/resources/base.rb +4 -0
- data/lib/monday/resources/board.rb +52 -0
- data/lib/monday/resources/column.rb +6 -0
- data/lib/monday/resources/file.rb +56 -0
- data/lib/monday/resources/folder.rb +55 -0
- data/lib/monday/resources/group.rb +66 -0
- data/lib/monday/resources/item.rb +62 -0
- data/lib/monday/util.rb +33 -1
- data/lib/monday/version.rb +1 -1
- data/lib/monday_ruby.rb +1 -0
- metadata +92 -11
- data/monday_ruby.gemspec +0 -39
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
# Pagination in monday.com
|
|
2
|
+
|
|
3
|
+
This document explains pagination concepts and how they apply to the monday.com API and the monday_ruby gem.
|
|
4
|
+
|
|
5
|
+
## What is Pagination?
|
|
6
|
+
|
|
7
|
+
Pagination is the practice of dividing large datasets into smaller, manageable chunks called "pages." Instead of retrieving thousands of records in a single API request, pagination allows you to fetch data incrementally.
|
|
8
|
+
|
|
9
|
+
### Why Pagination is Necessary
|
|
10
|
+
|
|
11
|
+
1. **Performance**: Loading thousands of items at once would be slow for both the server and client
|
|
12
|
+
2. **Memory**: Large datasets can exhaust available memory, especially on mobile devices
|
|
13
|
+
3. **Timeout prevention**: Long-running requests risk timing out before completion
|
|
14
|
+
4. **User experience**: Users can see results immediately rather than waiting for everything to load
|
|
15
|
+
5. **Network efficiency**: Smaller responses are faster to transmit and more resilient to connection issues
|
|
16
|
+
6. **Rate limiting**: Spreading requests across time helps stay within API rate limits
|
|
17
|
+
|
|
18
|
+
### The Alternative
|
|
19
|
+
|
|
20
|
+
Without pagination, fetching all items from a board with 10,000 items would:
|
|
21
|
+
- Take 10+ seconds to complete
|
|
22
|
+
- Use several megabytes of bandwidth
|
|
23
|
+
- Risk timeout on slower connections
|
|
24
|
+
- Potentially hit API complexity limits
|
|
25
|
+
- Load data users may never view
|
|
26
|
+
|
|
27
|
+
## Cursor-Based vs Offset-Based Pagination
|
|
28
|
+
|
|
29
|
+
There are two primary pagination strategies, each with distinct trade-offs.
|
|
30
|
+
|
|
31
|
+
### Offset-Based Pagination
|
|
32
|
+
|
|
33
|
+
Uses numeric offsets to specify starting positions:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
GET /items?offset=0&limit=25 # First page
|
|
37
|
+
GET /items?offset=25&limit=25 # Second page
|
|
38
|
+
GET /items?offset=50&limit=25 # Third page
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Advantages**:
|
|
42
|
+
- Simple to understand and implement
|
|
43
|
+
- Direct access to any page (e.g., "jump to page 5")
|
|
44
|
+
- Easy to calculate total pages
|
|
45
|
+
|
|
46
|
+
**Disadvantages**:
|
|
47
|
+
- Inconsistent results if data changes between requests (items added/deleted)
|
|
48
|
+
- Inefficient for large offsets (database must skip many rows)
|
|
49
|
+
- Difficult to handle concurrent modifications
|
|
50
|
+
- "Page drift" when items are added/removed during pagination
|
|
51
|
+
|
|
52
|
+
**Example of page drift**:
|
|
53
|
+
```
|
|
54
|
+
Initial state: [A, B, C, D, E, F, G, H]
|
|
55
|
+
|
|
56
|
+
Request 1 (offset=0, limit=3): Returns [A, B, C]
|
|
57
|
+
New item X inserted at position 0: [X, A, B, C, D, E, F, G, H]
|
|
58
|
+
Request 2 (offset=3, limit=3): Returns [C, D, E]
|
|
59
|
+
Result: Item C appears twice, B is skipped
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Cursor-Based Pagination
|
|
63
|
+
|
|
64
|
+
Uses opaque tokens (cursors) to mark positions in a dataset:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
GET /items?cursor=initial&limit=25
|
|
68
|
+
# Response includes next_cursor: "eyJpZCI6MTIzfQ=="
|
|
69
|
+
|
|
70
|
+
GET /items?cursor=eyJpZCI6MTIzfQ==&limit=25
|
|
71
|
+
# Response includes next_cursor: "eyJpZCI6MTQ4fQ=="
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Advantages**:
|
|
75
|
+
- Consistent results even when data changes
|
|
76
|
+
- Efficient at any depth in the dataset
|
|
77
|
+
- Handles concurrent modifications gracefully
|
|
78
|
+
- No duplicate or skipped items
|
|
79
|
+
|
|
80
|
+
**Disadvantages**:
|
|
81
|
+
- Cannot jump to arbitrary pages
|
|
82
|
+
- Cannot calculate total page count easily
|
|
83
|
+
- Cursors can become invalid
|
|
84
|
+
- More complex implementation
|
|
85
|
+
|
|
86
|
+
## Why monday.com Uses Cursor-Based Pagination
|
|
87
|
+
|
|
88
|
+
monday.com adopted cursor-based pagination for several architectural reasons:
|
|
89
|
+
|
|
90
|
+
### Real-Time Collaboration
|
|
91
|
+
|
|
92
|
+
monday.com is a collaborative platform where multiple users modify boards simultaneously:
|
|
93
|
+
- Items are created and deleted constantly
|
|
94
|
+
- Items move between groups
|
|
95
|
+
- Board structure changes frequently
|
|
96
|
+
|
|
97
|
+
Cursor-based pagination ensures that when you're iterating through items, you get a consistent view even as the board changes.
|
|
98
|
+
|
|
99
|
+
### Scalability
|
|
100
|
+
|
|
101
|
+
Large boards can have tens of thousands of items. Cursor-based pagination:
|
|
102
|
+
- Maintains consistent performance regardless of position in the dataset
|
|
103
|
+
- Uses database indexes efficiently
|
|
104
|
+
- Avoids expensive offset calculations
|
|
105
|
+
|
|
106
|
+
### API Design Philosophy
|
|
107
|
+
|
|
108
|
+
monday.com's GraphQL API emphasizes:
|
|
109
|
+
- **Reliability**: Cursors prevent duplicate or missed items
|
|
110
|
+
- **Efficiency**: Each request is optimized for the current state
|
|
111
|
+
- **Consistency**: The same cursor always points to the same logical position
|
|
112
|
+
|
|
113
|
+
## How Cursor Pagination Works
|
|
114
|
+
|
|
115
|
+
### Opaque Cursors
|
|
116
|
+
|
|
117
|
+
Cursors in monday.com are opaque strings - their internal structure is implementation-dependent and subject to change. A cursor might encode:
|
|
118
|
+
- Item ID
|
|
119
|
+
- Timestamp
|
|
120
|
+
- Sort order
|
|
121
|
+
- Filter criteria
|
|
122
|
+
|
|
123
|
+
**Important**: Treat cursors as opaque tokens. Never:
|
|
124
|
+
- Parse or decode cursors
|
|
125
|
+
- Construct cursors manually
|
|
126
|
+
- Make assumptions about cursor format
|
|
127
|
+
- Store cursors long-term
|
|
128
|
+
|
|
129
|
+
### Pagination Flow
|
|
130
|
+
|
|
131
|
+
1. **Initial request**: Don't provide a cursor
|
|
132
|
+
```ruby
|
|
133
|
+
response = client.item.items_page(
|
|
134
|
+
args: { limit: 25, query_params: { boards: [123] } }
|
|
135
|
+
)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
2. **Extract cursor**: Get the cursor from the response
|
|
139
|
+
```ruby
|
|
140
|
+
cursor = response.dig("data", "items_page", "cursor")
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
3. **Subsequent requests**: Pass the cursor to get the next page
|
|
144
|
+
```ruby
|
|
145
|
+
next_page = client.item.items_page(
|
|
146
|
+
args: { limit: 25, cursor: cursor, query_params: { boards: [123] } }
|
|
147
|
+
)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
4. **Detect end**: When there's no more data, the cursor may be nil or empty
|
|
151
|
+
|
|
152
|
+
### Cursor Characteristics
|
|
153
|
+
|
|
154
|
+
- **Stateful**: Encodes position in a specific query result set
|
|
155
|
+
- **Query-specific**: A cursor from one query won't work with a different query
|
|
156
|
+
- **Time-sensitive**: Cursors expire after a certain period
|
|
157
|
+
- **Opaque**: Internal format is not guaranteed or documented
|
|
158
|
+
- **Forward-only**: Can only move forward through results
|
|
159
|
+
|
|
160
|
+
## Cursor Expiration
|
|
161
|
+
|
|
162
|
+
monday.com cursors expire after **60 minutes** of inactivity.
|
|
163
|
+
|
|
164
|
+
### Why Cursors Expire
|
|
165
|
+
|
|
166
|
+
1. **Resource management**: Servers don't maintain pagination state indefinitely
|
|
167
|
+
2. **Data consistency**: Prevents using stale cursors on significantly changed data
|
|
168
|
+
3. **Security**: Limits the window for cursor-based attacks or abuse
|
|
169
|
+
4. **Cache invalidation**: Allows backend caches to be cleared periodically
|
|
170
|
+
|
|
171
|
+
### Handling Expiration
|
|
172
|
+
|
|
173
|
+
When a cursor expires:
|
|
174
|
+
- The API returns an error indicating the cursor is invalid
|
|
175
|
+
- You must restart pagination from the beginning
|
|
176
|
+
- Previously fetched data remains valid
|
|
177
|
+
|
|
178
|
+
### Best Practices
|
|
179
|
+
|
|
180
|
+
- **Process promptly**: Don't hold cursors for extended periods
|
|
181
|
+
- **Handle errors**: Detect expired cursor errors and restart
|
|
182
|
+
- **Avoid storing**: Don't persist cursors in databases or long-term storage
|
|
183
|
+
- **Complete iterations**: Finish paginating through results in a single session when possible
|
|
184
|
+
|
|
185
|
+
### Expiration Example
|
|
186
|
+
|
|
187
|
+
```ruby
|
|
188
|
+
# Start pagination at 10:00 AM
|
|
189
|
+
cursor = get_first_page_cursor()
|
|
190
|
+
|
|
191
|
+
# Wait 65 minutes...
|
|
192
|
+
|
|
193
|
+
# Use cursor at 11:05 AM - will fail!
|
|
194
|
+
begin
|
|
195
|
+
next_page = get_page(cursor)
|
|
196
|
+
rescue Monday::InvalidCursorError
|
|
197
|
+
# Cursor expired, restart pagination
|
|
198
|
+
cursor = get_first_page_cursor()
|
|
199
|
+
next_page = get_page(cursor)
|
|
200
|
+
end
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Pagination Performance Considerations
|
|
204
|
+
|
|
205
|
+
### Page Size Trade-offs
|
|
206
|
+
|
|
207
|
+
Choosing the right page size (limit parameter) involves balancing competing factors:
|
|
208
|
+
|
|
209
|
+
**Small pages (e.g., 10-25 items)**:
|
|
210
|
+
- Lower latency per request
|
|
211
|
+
- Less memory usage
|
|
212
|
+
- More requests needed to fetch all data
|
|
213
|
+
- Higher total time for complete dataset
|
|
214
|
+
- More API calls (impacts rate limits)
|
|
215
|
+
|
|
216
|
+
**Large pages (e.g., 100-500 items)**:
|
|
217
|
+
- Higher latency per request
|
|
218
|
+
- More memory usage
|
|
219
|
+
- Fewer requests needed
|
|
220
|
+
- Lower total time for complete dataset
|
|
221
|
+
- Fewer API calls
|
|
222
|
+
|
|
223
|
+
**Optimal page size depends on**:
|
|
224
|
+
- Network speed and reliability
|
|
225
|
+
- Available memory
|
|
226
|
+
- UI/UX requirements (how much to show at once)
|
|
227
|
+
- Rate limit constraints
|
|
228
|
+
- Total dataset size
|
|
229
|
+
|
|
230
|
+
### monday.com Limits
|
|
231
|
+
|
|
232
|
+
monday.com enforces limits on page size:
|
|
233
|
+
- Maximum items per page varies by endpoint
|
|
234
|
+
- Typically capped at 100-500 items
|
|
235
|
+
- Larger limits consume more API complexity budget
|
|
236
|
+
|
|
237
|
+
### Network Efficiency
|
|
238
|
+
|
|
239
|
+
Cursor-based pagination is network-efficient:
|
|
240
|
+
- Only requested data is transmitted
|
|
241
|
+
- Subsequent requests reuse connection pooling
|
|
242
|
+
- Cursors are small (typically under 100 bytes)
|
|
243
|
+
- Partial failures can be retried from last successful cursor
|
|
244
|
+
|
|
245
|
+
### Caching Considerations
|
|
246
|
+
|
|
247
|
+
Cursor-based pagination affects caching strategies:
|
|
248
|
+
- Individual pages can be cached using cursor as key
|
|
249
|
+
- Cache expiration should align with cursor expiration (60 minutes)
|
|
250
|
+
- First page (no cursor) is often most heavily cached
|
|
251
|
+
- Personalized or filtered queries are harder to cache
|
|
252
|
+
|
|
253
|
+
## items_page vs Deprecated items Field
|
|
254
|
+
|
|
255
|
+
monday.com's GraphQL API has evolved its pagination approach.
|
|
256
|
+
|
|
257
|
+
### Legacy: items Field
|
|
258
|
+
|
|
259
|
+
The original `items` field on boards returned all items without pagination:
|
|
260
|
+
|
|
261
|
+
```graphql
|
|
262
|
+
query {
|
|
263
|
+
boards(ids: [123]) {
|
|
264
|
+
items {
|
|
265
|
+
id
|
|
266
|
+
name
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Problems**:
|
|
273
|
+
- No pagination support
|
|
274
|
+
- Returns all items at once
|
|
275
|
+
- Performance degrades with large boards
|
|
276
|
+
- Timeout risk on boards with many items
|
|
277
|
+
- High API complexity cost
|
|
278
|
+
|
|
279
|
+
### Modern: items_page Query
|
|
280
|
+
|
|
281
|
+
The `items_page` query provides cursor-based pagination:
|
|
282
|
+
|
|
283
|
+
```graphql
|
|
284
|
+
query {
|
|
285
|
+
items_page(limit: 25, query_params: {boards: [123]}) {
|
|
286
|
+
cursor
|
|
287
|
+
items {
|
|
288
|
+
id
|
|
289
|
+
name
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Advantages**:
|
|
296
|
+
- Efficient pagination with cursors
|
|
297
|
+
- Consistent performance regardless of board size
|
|
298
|
+
- Lower complexity per request
|
|
299
|
+
- Better resource utilization
|
|
300
|
+
- Query parameters for filtering
|
|
301
|
+
|
|
302
|
+
### Migration Path
|
|
303
|
+
|
|
304
|
+
monday.com deprecated the `items` field to encourage pagination:
|
|
305
|
+
- New applications should use `items_page`
|
|
306
|
+
- Existing applications should migrate to avoid deprecation
|
|
307
|
+
- The `items` field may be removed in future API versions
|
|
308
|
+
|
|
309
|
+
The monday_ruby gem provides methods for both:
|
|
310
|
+
- `client.board.items` - legacy (deprecated)
|
|
311
|
+
- `client.item.items_page` - modern (recommended)
|
|
312
|
+
|
|
313
|
+
## Query Parameters and Filtering with Pagination
|
|
314
|
+
|
|
315
|
+
The `items_page` query supports filtering through query parameters, which interact with pagination in important ways.
|
|
316
|
+
|
|
317
|
+
### Query Parameters
|
|
318
|
+
|
|
319
|
+
Common filters include:
|
|
320
|
+
- `boards`: Limit to specific boards
|
|
321
|
+
- `state`: Filter by item state (active, archived, deleted)
|
|
322
|
+
- `order_by`: Sort order for results
|
|
323
|
+
|
|
324
|
+
```ruby
|
|
325
|
+
client.item.items_page(
|
|
326
|
+
args: {
|
|
327
|
+
limit: 25,
|
|
328
|
+
query_params: {
|
|
329
|
+
boards: [123, 456],
|
|
330
|
+
state: "active",
|
|
331
|
+
order_by: [{ column_id: "date", direction: "desc" }]
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
)
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Cursor-Filter Coupling
|
|
338
|
+
|
|
339
|
+
Cursors are tied to their query parameters:
|
|
340
|
+
- A cursor from a filtered query only works with the same filter
|
|
341
|
+
- Changing `query_params` invalidates the cursor
|
|
342
|
+
- The cursor encodes both position and query context
|
|
343
|
+
|
|
344
|
+
**Example of what NOT to do**:
|
|
345
|
+
```ruby
|
|
346
|
+
# Request 1: Filter by board 123
|
|
347
|
+
response1 = items_page(query_params: { boards: [123] })
|
|
348
|
+
cursor = response1["cursor"]
|
|
349
|
+
|
|
350
|
+
# Request 2: Try to use cursor with different filter - ERROR!
|
|
351
|
+
response2 = items_page(cursor: cursor, query_params: { boards: [456] })
|
|
352
|
+
# This will fail - cursor is specific to board 123
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Filtering Best Practices
|
|
356
|
+
|
|
357
|
+
1. **Keep filters consistent**: Use identical `query_params` throughout pagination
|
|
358
|
+
2. **Filter early**: Apply filters in the initial request, not on fetched results
|
|
359
|
+
3. **Understand costs**: Complex filters may increase API complexity
|
|
360
|
+
4. **Combine operations**: Fetch and filter in a single request rather than multiple
|
|
361
|
+
|
|
362
|
+
### Pagination with Sorting
|
|
363
|
+
|
|
364
|
+
When using `order_by`, cursors maintain the sort order:
|
|
365
|
+
- Results remain sorted across all pages
|
|
366
|
+
- Cursor position is relative to the sorted sequence
|
|
367
|
+
- Changing sort order invalidates the cursor
|
|
368
|
+
|
|
369
|
+
## Trade-offs: Page Size vs API Calls
|
|
370
|
+
|
|
371
|
+
Determining optimal pagination strategy requires analyzing multiple dimensions.
|
|
372
|
+
|
|
373
|
+
### Scenario 1: Display 25 Items to User
|
|
374
|
+
|
|
375
|
+
If you only need to show 25 items:
|
|
376
|
+
- Set `limit: 25`
|
|
377
|
+
- Make 1 API call
|
|
378
|
+
- Minimal complexity
|
|
379
|
+
- Fastest time-to-display
|
|
380
|
+
|
|
381
|
+
### Scenario 2: Process All 1,000 Items
|
|
382
|
+
|
|
383
|
+
If you need to process every item on a board:
|
|
384
|
+
|
|
385
|
+
**Option A: Small pages (25 items)**
|
|
386
|
+
- 40 API calls required
|
|
387
|
+
- 40× authentication overhead
|
|
388
|
+
- 40× network round-trips
|
|
389
|
+
- Lower memory footprint
|
|
390
|
+
- Can start processing sooner
|
|
391
|
+
- More resilient to failures (restart from last cursor)
|
|
392
|
+
|
|
393
|
+
**Option B: Large pages (100 items)**
|
|
394
|
+
- 10 API calls required
|
|
395
|
+
- 10× authentication overhead
|
|
396
|
+
- 10× network round-trips
|
|
397
|
+
- Higher memory footprint
|
|
398
|
+
- Longer wait before processing starts
|
|
399
|
+
- More data lost on failure
|
|
400
|
+
|
|
401
|
+
### Scenario 3: Rate-Limited Environment
|
|
402
|
+
|
|
403
|
+
If you're close to rate limits:
|
|
404
|
+
- Larger pages reduce total API calls
|
|
405
|
+
- But larger pages have higher complexity per call
|
|
406
|
+
- Must balance: fewer calls vs complexity budget
|
|
407
|
+
- May need to add delays between requests
|
|
408
|
+
|
|
409
|
+
### Scenario 4: Real-Time Updates
|
|
410
|
+
|
|
411
|
+
If displaying data as it loads:
|
|
412
|
+
- Smaller pages provide faster initial display
|
|
413
|
+
- Users see results immediately
|
|
414
|
+
- Can implement infinite scroll or "load more"
|
|
415
|
+
- Better perceived performance
|
|
416
|
+
|
|
417
|
+
### Calculation Example
|
|
418
|
+
|
|
419
|
+
Board with 1,000 items, rate limit of 100 requests/minute:
|
|
420
|
+
|
|
421
|
+
**25-item pages**:
|
|
422
|
+
- Requests needed: 40
|
|
423
|
+
- Time at max rate: 24 seconds (within limit)
|
|
424
|
+
- Memory per page: ~25 KB
|
|
425
|
+
- Total transfer: ~1 MB
|
|
426
|
+
|
|
427
|
+
**100-item pages**:
|
|
428
|
+
- Requests needed: 10
|
|
429
|
+
- Time at max rate: 6 seconds
|
|
430
|
+
- Memory per page: ~100 KB
|
|
431
|
+
- Total transfer: ~1 MB
|
|
432
|
+
|
|
433
|
+
Same total data transferred, but different time and memory profiles.
|
|
434
|
+
|
|
435
|
+
## Conclusion
|
|
436
|
+
|
|
437
|
+
Pagination is a fundamental aspect of working with the monday.com API. Understanding cursor-based pagination - its advantages over offset pagination, how cursors work, their expiration behavior, and the trade-offs in page sizing - is essential for building efficient, reliable applications.
|
|
438
|
+
|
|
439
|
+
Key takeaways:
|
|
440
|
+
- monday.com uses cursor-based pagination for consistency and performance
|
|
441
|
+
- Cursors are opaque, stateful, and expire after 60 minutes
|
|
442
|
+
- Use `items_page` instead of the deprecated `items` field
|
|
443
|
+
- Page size involves trade-offs between latency, memory, and API calls
|
|
444
|
+
- Query parameters must remain consistent throughout pagination
|
|
445
|
+
- Proper pagination design significantly impacts application performance and user experience
|
|
446
|
+
|
|
447
|
+
The monday_ruby gem abstracts the mechanics of cursor handling while preserving GraphQL's pagination semantics, but understanding these underlying concepts enables you to make informed decisions about pagination strategy in your applications.
|