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,356 @@
|
|
|
1
|
+
# GraphQL and the monday.com API
|
|
2
|
+
|
|
3
|
+
This document explains GraphQL fundamentals and how they relate to the monday.com API and the monday_ruby gem.
|
|
4
|
+
|
|
5
|
+
## What is GraphQL?
|
|
6
|
+
|
|
7
|
+
GraphQL is a query language for APIs and a runtime for executing those queries. Unlike traditional REST APIs where the server determines the structure of responses, GraphQL allows clients to request exactly the data they need, nothing more and nothing less.
|
|
8
|
+
|
|
9
|
+
Developed by Facebook in 2012 and open-sourced in 2015, GraphQL addresses common pain points in API design:
|
|
10
|
+
|
|
11
|
+
- **Over-fetching**: REST endpoints often return more data than needed
|
|
12
|
+
- **Under-fetching**: Multiple REST requests may be needed to gather related data
|
|
13
|
+
- **API versioning**: GraphQL schemas evolve without breaking existing queries
|
|
14
|
+
- **Strong typing**: The GraphQL type system provides clear contracts between client and server
|
|
15
|
+
|
|
16
|
+
## Why monday.com Uses GraphQL
|
|
17
|
+
|
|
18
|
+
monday.com chose GraphQL for its API because of the platform's inherently relational and flexible nature:
|
|
19
|
+
|
|
20
|
+
1. **Complex data relationships**: Boards contain groups, groups contain items, items have columns, columns have values, and all these entities are interconnected
|
|
21
|
+
2. **Flexible data structures**: Different boards have different column types and configurations
|
|
22
|
+
3. **Client efficiency**: Applications can fetch exactly what they need in a single request
|
|
23
|
+
4. **Schema introspection**: The API is self-documenting, making it easier for developers to explore
|
|
24
|
+
|
|
25
|
+
## GraphQL vs REST APIs
|
|
26
|
+
|
|
27
|
+
### REST Approach
|
|
28
|
+
|
|
29
|
+
In a REST API, you might need multiple requests to get board data:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
GET /boards/123
|
|
33
|
+
GET /boards/123/groups
|
|
34
|
+
GET /boards/123/items
|
|
35
|
+
GET /items/456/column_values
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Each endpoint returns a fixed structure, often including data you don't need.
|
|
39
|
+
|
|
40
|
+
### GraphQL Approach
|
|
41
|
+
|
|
42
|
+
With GraphQL, you make a single request specifying exactly what you want:
|
|
43
|
+
|
|
44
|
+
```graphql
|
|
45
|
+
query {
|
|
46
|
+
boards(ids: [123]) {
|
|
47
|
+
name
|
|
48
|
+
groups {
|
|
49
|
+
title
|
|
50
|
+
items {
|
|
51
|
+
name
|
|
52
|
+
column_values {
|
|
53
|
+
id
|
|
54
|
+
text
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The response structure matches your query structure, containing only the requested fields.
|
|
63
|
+
|
|
64
|
+
## Query vs Mutation Operations
|
|
65
|
+
|
|
66
|
+
GraphQL distinguishes between two primary operation types:
|
|
67
|
+
|
|
68
|
+
### Queries
|
|
69
|
+
|
|
70
|
+
Queries are read-only operations that fetch data. They're similar to HTTP GET requests but with precise field selection:
|
|
71
|
+
|
|
72
|
+
```graphql
|
|
73
|
+
query {
|
|
74
|
+
boards(ids: [123, 456]) {
|
|
75
|
+
id
|
|
76
|
+
name
|
|
77
|
+
state
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Queries can be executed in parallel and are generally safe to retry or cache.
|
|
83
|
+
|
|
84
|
+
### Mutations
|
|
85
|
+
|
|
86
|
+
Mutations modify server-side data (create, update, delete). They're analogous to POST, PUT, PATCH, and DELETE in REST:
|
|
87
|
+
|
|
88
|
+
```graphql
|
|
89
|
+
mutation {
|
|
90
|
+
create_board(board_name: "New Project", board_kind: public) {
|
|
91
|
+
id
|
|
92
|
+
name
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Mutations are executed sequentially in the order specified, ensuring predictable side effects.
|
|
98
|
+
|
|
99
|
+
## GraphQL Schema and Types
|
|
100
|
+
|
|
101
|
+
The GraphQL schema defines the API's type system - what data is available and how it's structured.
|
|
102
|
+
|
|
103
|
+
### Core Concepts
|
|
104
|
+
|
|
105
|
+
- **Types**: Define objects (like `Board`, `Item`, `User`) with specific fields
|
|
106
|
+
- **Fields**: Properties on types that can be queried
|
|
107
|
+
- **Scalars**: Primitive types like `String`, `Int`, `Boolean`, `ID`
|
|
108
|
+
- **Enums**: Fixed sets of allowed values
|
|
109
|
+
- **Non-null**: Fields that are guaranteed to return a value (marked with `!`)
|
|
110
|
+
|
|
111
|
+
### monday.com's Schema
|
|
112
|
+
|
|
113
|
+
The monday.com schema reflects its data model:
|
|
114
|
+
|
|
115
|
+
- `Board` type has fields like `name`, `groups`, `items`, `columns`
|
|
116
|
+
- `Item` type has fields like `name`, `column_values`, `group`, `board`
|
|
117
|
+
- `ColumnValue` is an interface with different implementations for each column type
|
|
118
|
+
|
|
119
|
+
This strongly-typed schema enables:
|
|
120
|
+
- Validation at query time
|
|
121
|
+
- Intelligent autocomplete in development tools
|
|
122
|
+
- Clear documentation of available fields
|
|
123
|
+
- Type safety in client applications
|
|
124
|
+
|
|
125
|
+
## Field Selection in GraphQL
|
|
126
|
+
|
|
127
|
+
Field selection is one of GraphQL's most powerful features. You specify exactly which fields you want in your response.
|
|
128
|
+
|
|
129
|
+
### Simple Selection
|
|
130
|
+
|
|
131
|
+
```graphql
|
|
132
|
+
query {
|
|
133
|
+
boards(ids: [123]) {
|
|
134
|
+
id
|
|
135
|
+
name
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Returns only `id` and `name` for each board.
|
|
141
|
+
|
|
142
|
+
### Nested Selection
|
|
143
|
+
|
|
144
|
+
```graphql
|
|
145
|
+
query {
|
|
146
|
+
boards(ids: [123]) {
|
|
147
|
+
name
|
|
148
|
+
groups {
|
|
149
|
+
title
|
|
150
|
+
items {
|
|
151
|
+
name
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Traverse relationships by selecting fields on nested objects.
|
|
159
|
+
|
|
160
|
+
### Why This Matters
|
|
161
|
+
|
|
162
|
+
- **Performance**: Smaller payloads mean faster responses
|
|
163
|
+
- **Bandwidth**: Critical for mobile applications
|
|
164
|
+
- **Clarity**: The query documents exactly what data the application uses
|
|
165
|
+
- **Backend optimization**: Servers can optimize based on what's requested
|
|
166
|
+
|
|
167
|
+
## Arguments and Variables
|
|
168
|
+
|
|
169
|
+
GraphQL fields can accept arguments to filter, sort, or modify their behavior.
|
|
170
|
+
|
|
171
|
+
### Inline Arguments
|
|
172
|
+
|
|
173
|
+
```graphql
|
|
174
|
+
query {
|
|
175
|
+
boards(ids: [123, 456], limit: 10) {
|
|
176
|
+
name
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Variables
|
|
182
|
+
|
|
183
|
+
For dynamic queries, use variables instead of hardcoding values:
|
|
184
|
+
|
|
185
|
+
```graphql
|
|
186
|
+
query GetBoards($boardIds: [ID!]!) {
|
|
187
|
+
boards(ids: $boardIds) {
|
|
188
|
+
name
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Variables are passed separately from the query:
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"boardIds": [123, 456]
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
This separation enables:
|
|
202
|
+
- Query reuse with different values
|
|
203
|
+
- Better caching (queries are the same, only variables change)
|
|
204
|
+
- Automatic input validation
|
|
205
|
+
- Protection against injection attacks
|
|
206
|
+
|
|
207
|
+
## How monday_ruby Abstracts GraphQL
|
|
208
|
+
|
|
209
|
+
The monday_ruby gem provides a Ruby-friendly interface to the GraphQL API while preserving its flexibility.
|
|
210
|
+
|
|
211
|
+
### Query Building
|
|
212
|
+
|
|
213
|
+
Instead of writing GraphQL strings, you use Ruby methods:
|
|
214
|
+
|
|
215
|
+
```ruby
|
|
216
|
+
client.board.query(
|
|
217
|
+
args: { ids: [123, 456] },
|
|
218
|
+
select: ["id", "name", { groups: ["title", "id"] }]
|
|
219
|
+
)
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The gem converts this to:
|
|
223
|
+
|
|
224
|
+
```graphql
|
|
225
|
+
query{boards(ids: [123, 456]){id name groups{title id}}}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Why This Abstraction?
|
|
229
|
+
|
|
230
|
+
1. **Ruby idioms**: Use Ruby hashes and arrays instead of GraphQL syntax
|
|
231
|
+
2. **Dynamic queries**: Build queries programmatically based on runtime conditions
|
|
232
|
+
3. **Error handling**: Translate GraphQL errors into Ruby exceptions
|
|
233
|
+
4. **Reduced boilerplate**: Authentication and HTTP handling are automatic
|
|
234
|
+
5. **Type safety**: Ruby's dynamic nature with GraphQL's strict types
|
|
235
|
+
|
|
236
|
+
### The Trade-off
|
|
237
|
+
|
|
238
|
+
The abstraction means you're not writing raw GraphQL, which:
|
|
239
|
+
- **Advantage**: Faster development, more Ruby-like code
|
|
240
|
+
- **Disadvantage**: You still need to understand GraphQL concepts to use the API effectively
|
|
241
|
+
|
|
242
|
+
## Why Understanding GraphQL Helps
|
|
243
|
+
|
|
244
|
+
Even with monday_ruby's abstraction, GraphQL knowledge is valuable:
|
|
245
|
+
|
|
246
|
+
1. **Field selection**: Knowing what fields are available and how they relate
|
|
247
|
+
2. **Query optimization**: Understanding how to request only necessary data
|
|
248
|
+
3. **Error interpretation**: GraphQL errors reference fields and types
|
|
249
|
+
4. **Rate limiting**: GraphQL complexity calculations affect your limits
|
|
250
|
+
5. **Documentation**: monday.com's API docs use GraphQL terminology
|
|
251
|
+
6. **Debugging**: Network inspection shows GraphQL queries and responses
|
|
252
|
+
7. **Advanced features**: Aliases, fragments, directives require GraphQL understanding
|
|
253
|
+
|
|
254
|
+
## GraphQL Complexity and Rate Limiting
|
|
255
|
+
|
|
256
|
+
GraphQL's flexibility creates a challenge: queries can be arbitrarily complex and expensive.
|
|
257
|
+
|
|
258
|
+
### Complexity Calculation
|
|
259
|
+
|
|
260
|
+
monday.com assigns complexity points to each field based on computational cost:
|
|
261
|
+
|
|
262
|
+
- Simple scalar fields: Low complexity (1-5 points)
|
|
263
|
+
- Relationships: Medium complexity (10-20 points)
|
|
264
|
+
- Mutations: Higher complexity (20-50+ points)
|
|
265
|
+
|
|
266
|
+
A query's total complexity is the sum of all requested fields.
|
|
267
|
+
|
|
268
|
+
### Rate Limits
|
|
269
|
+
|
|
270
|
+
monday.com enforces limits based on:
|
|
271
|
+
- **Complexity budget**: Maximum complexity per time window
|
|
272
|
+
- **Request frequency**: Number of requests per minute
|
|
273
|
+
- **Account tier**: Different limits for different subscription levels
|
|
274
|
+
|
|
275
|
+
### Optimization Strategies
|
|
276
|
+
|
|
277
|
+
Understanding complexity helps you:
|
|
278
|
+
- Select only necessary fields to reduce complexity
|
|
279
|
+
- Batch multiple operations into single queries
|
|
280
|
+
- Use pagination to spread load across requests
|
|
281
|
+
- Cache frequently accessed data
|
|
282
|
+
- Monitor complexity through response headers
|
|
283
|
+
|
|
284
|
+
## monday.com's GraphQL API Specifics
|
|
285
|
+
|
|
286
|
+
### API Version
|
|
287
|
+
|
|
288
|
+
monday.com versions its API (e.g., "2023-07", "2024-01"). Versions are specified via headers and control:
|
|
289
|
+
- Available fields and types
|
|
290
|
+
- Deprecation of old features
|
|
291
|
+
- Changes to field behavior
|
|
292
|
+
|
|
293
|
+
The monday_ruby gem allows configuring the version:
|
|
294
|
+
|
|
295
|
+
```ruby
|
|
296
|
+
client = Monday::Client.new(token: "...", version: "2024-01")
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Mutation Response Patterns
|
|
300
|
+
|
|
301
|
+
monday.com mutations return the created or modified object, allowing you to:
|
|
302
|
+
1. Confirm the operation succeeded
|
|
303
|
+
2. Get the new object's ID
|
|
304
|
+
3. Fetch updated field values
|
|
305
|
+
|
|
306
|
+
```graphql
|
|
307
|
+
mutation {
|
|
308
|
+
create_item(board_id: 123, item_name: "Task") {
|
|
309
|
+
id
|
|
310
|
+
name
|
|
311
|
+
created_at
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Error Responses
|
|
317
|
+
|
|
318
|
+
GraphQL errors are returned in the response alongside data (if any):
|
|
319
|
+
|
|
320
|
+
```json
|
|
321
|
+
{
|
|
322
|
+
"data": { ... },
|
|
323
|
+
"errors": [
|
|
324
|
+
{
|
|
325
|
+
"message": "Field 'invalid_field' doesn't exist",
|
|
326
|
+
"locations": [{"line": 2, "column": 3}]
|
|
327
|
+
}
|
|
328
|
+
]
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
This allows partial success: some fields may return data while others error.
|
|
333
|
+
|
|
334
|
+
### Nested Mutations
|
|
335
|
+
|
|
336
|
+
monday.com supports mutations that affect multiple related entities:
|
|
337
|
+
|
|
338
|
+
```graphql
|
|
339
|
+
mutation {
|
|
340
|
+
create_board(board_name: "Project") {
|
|
341
|
+
id
|
|
342
|
+
groups {
|
|
343
|
+
id
|
|
344
|
+
title
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
The mutation creates a board and returns its auto-generated groups in one operation.
|
|
351
|
+
|
|
352
|
+
## Conclusion
|
|
353
|
+
|
|
354
|
+
GraphQL is fundamental to how monday.com's API works. While monday_ruby abstracts the syntax, understanding GraphQL concepts - queries vs mutations, field selection, arguments, complexity, and the type system - enables you to use the gem effectively and efficiently.
|
|
355
|
+
|
|
356
|
+
The monday.com API's GraphQL implementation prioritizes flexibility and efficiency, allowing you to fetch complex, interconnected data in single requests while maintaining strong typing and introspection capabilities. This design philosophy directly influences how you structure queries and mutations through the monday_ruby gem.
|