File: using_connections.md

package info (click to toggle)
ruby-graphql 2.2.17-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,584 kB
  • sloc: ruby: 67,505; ansic: 1,753; yacc: 831; javascript: 331; makefile: 6
file content (136 lines) | stat: -rw-r--r-- 4,937 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
---
layout: guide
doc_stub: false
search: true
section: Pagination
title: Using Connections
desc: Pagination with GraphQL-Ruby's built-in connections
index: 2
---

GraphQL-Ruby ships with a few implementations of the {% internal_link "connection pattern", "pagination/connection_concepts" %} that you can use out of the box. They support Ruby Arrays, Mongoid, Sequel, and ActiveRecord.

Additionally, connections allow you to limit the number of items returned with [`max_page_size`](#max-page-size) and set the default number of items returned with [`default_page_size`](#default-page-size).

## Make Connection Fields

Use `.connection_type` to generate a connection type for paginating over objects of a given type:

```ruby
field :items, Types::ItemType.connection_type, null: false
```

The generated return type will be called `ItemConnection`. Since it ends in `*Connection`, the `field(...)` will automatically be configured with `connection: true`. If the connection type's name doesn't end in `Connection`, you have to add that configuration yourself:

```ruby
# here's a custom type whose name doesn't end in "Connection", so `connection: true` is required:
field :items, Types::ItemConnectionPage, null: false, connection: true
```

The field will be given some arguments by default: `first`, `last`, `after`, and `before`.

### Opting out of default connection handling

To opt out of GraphQL-Ruby's default connection handling, add `connection: false` to the field definition:

```diff
- field :items, Types::ItemType.connection_type, null: false
+ field :items, Types::ItemType.connection_type, null: false, connection: false
```

Then, add any arguments you want (`first`, `last`, `after`, `before`) and make sure that your resolver returns an object that can fulfill the fields of the configured return type.

## Return Collections

With connection fields, you can return collection objects from fields or resolvers:

```ruby
def items
  object.items # => eg, returns an ActiveRecord Relation
end
```

The collection object (Array, Mongoid relation, Sequel dataset, ActiveRecord relation) will be automatically paginated with the provided arguments. Cursors will be generated based on the offset of nodes in the collection.

## Make Custom Connections

If you want to paginate something that _isn't_ supported out-of-the-box, you can implement your own pagination wrapper and hook it up to GraphQL-Ruby. Read more in {% internal_link "Custom Connections", "/pagination/custom_connections" %}.

## Special Cases

Sometimes, you have _one collection_ that needs special handling, unlike other instances of its class. For cases like this, you can manually apply the connection wrapper in the resolver. For example:

```ruby
def items
  # Get the ActiveRecord relation to paginate
  relation = object.items
  # Apply a custom wrapper
  Connections::ItemsConnection.new(relation)
end
```

This way, you can handle this _particular_ `relation` with custom code.

## Max Page Size

You can apply `max_page_size` to limit the number of items returned and queried from the database, regardless of what the client requests.

- __For the whole schema__, you can add it to your schema definition:

```ruby
class MyAppSchema < GraphQL::Schema
  default_max_page_size 50
end
```

  At runtime, that value will be applied to _every_ connection, unless an override is provided as described below.

- __For a given field__, add it to the field definition with a keyword:

```ruby
field :items, Item.connection_type, null: false,
  max_page_size: 25
```

- __Dynamically__, you can add `max_page_size:` when you apply custom connection wrappers:

```ruby
def items
  relation = object.items
  Connections::ItemsConnection.new(relation, max_page_size: 10)
end
```

To _remove_ a `max_page_size` setting, you can pass `nil`. That will allow unbounded collections to be returned to clients.

## Default Page Size

You can apply `default_page_size` to limit the number of items returned and queried from the database when no `first` or `last` is provided.

- __For the whole schema__, you can add it to your schema definition:

```ruby
class MyAppSchema < GraphQL::Schema
  default_page_size 50
end
```

  At runtime, that value will be applied to _every_ connection, unless an override is provided as described below.

- __For a given field__, add it to the field definition with a keyword:

```ruby
field :items, Item.connection_type, null: false,
  default_page_size: 25
```

- __Dynamically__, you can add `default_page_size:` when you apply custom connection wrappers:

```ruby
def items
  relation = object.items
  Connections::ItemsConnection.new(relation, default_page_size: 10)
end
```

If `max_page_size` is set and `default_page_size` is higher than it, the `default_page_size` will be clamped down to match `max_page_size`. If both `default_page_size` and `max_page_size` are set to `nil`, unbounded collections will be returned.