Class: GraphQL::Pagination::Connection
- Inherits:
-
Object
- Object
- GraphQL::Pagination::Connection
- Defined in:
- lib/graphql/pagination/connection.rb
Overview
A Connection wraps a list of items and provides cursor-based pagination over it.
Connections were introduced by Facebook’s Relay front-end framework, but
proved to be generally useful for GraphQL APIs. When in doubt, use connections
to serve lists (like Arrays, ActiveRecord::Relations) via GraphQL.
Unlike the previous connection implementation, these default to bidirectional pagination.
Pagination arguments and context may be provided at initialization or assigned later (see Schema::Field::ConnectionExtension).
Direct Known Subclasses
Defined Under Namespace
Classes: Edge, PaginationImplementationMissingError
Instance Attribute Summary collapse
-
#after_value ⇒ Object
Raw access to client-provided values.
-
#arguments ⇒ Hash<Symbol => Object>
The field arguments from the field that returned this connection.
-
#before_value ⇒ Object
Raw access to client-provided values.
-
#context ⇒ GraphQL::Query::Context
-
#edge_class ⇒ Class
A wrapper class for edges of this connection.
-
#field ⇒ GraphQL::Schema::Field
The field this connection was returned by.
-
#first ⇒ Integer?
A clamped
firstvalue. -
#first_value ⇒ Object
Raw access to client-provided values.
-
#items ⇒ Object
readonly
A list object, from the application.
-
#last ⇒ Integer?
A clamped
lastvalue. -
#last_value ⇒ Object
Raw access to client-provided values.
-
#parent ⇒ Object
The object this collection belongs to.
-
#was_authorized_by_scope_items ⇒ Object
writeonly
Sets the attribute was_authorized_by_scope_items.
Instance Method Summary collapse
-
#after ⇒ String?
The client-provided cursor.
-
#before ⇒ String?
The client-provided cursor.
-
#cursor_for(item) ⇒ String
Return a cursor for this item.
-
#default_page_size ⇒ Object
-
#default_page_size=(new_value) ⇒ Object
-
#edge_nodes ⇒ Object
deprecated
Deprecated.
use #nodes instead
-
#edges ⇒ Array<Edge>
#nodes, but wrapped with Edge instances.
-
#end_cursor ⇒ String
The cursor of the last item in #nodes.
-
#has_default_page_size_override? ⇒ Boolean
-
#has_max_page_size_override? ⇒ Boolean
-
#has_next_page ⇒ Boolean
True if there are more items after this page.
-
#has_previous_page ⇒ Boolean
True if there were items before these items.
-
#initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, last: nil, before: nil, edge_class: nil, arguments: nil) ⇒ Connection
constructor
A new instance of Connection.
-
#max_page_size ⇒ Object
-
#max_page_size=(new_value) ⇒ Object
-
#nodes ⇒ Array<Object>
A slice of #items, constrained by @first_value/@after_value/@last_value/@before_value.
-
#page_info ⇒ Object
The connection object itself implements
PageInfofields. -
#range_add_edge(item) ⇒ Edge
This is called by
Relay::RangeAdd– it can be overridden whenitemneeds some modifications based on this connection’s state. -
#start_cursor ⇒ String
The cursor of the first item in #nodes.
-
#was_authorized_by_scope_items? ⇒ Boolean
Constructor Details
#initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, last: nil, before: nil, edge_class: nil, arguments: nil) ⇒ Connection
Returns a new instance of Connection.
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 |
# File 'lib/graphql/pagination/connection.rb', line 69 def initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, last: nil, before: nil, edge_class: nil, arguments: nil) @items = items @parent = parent @context = context @field = field @first_value = first @after_value = after @last_value = last @before_value = before @arguments = arguments @edge_class = edge_class || self.class::Edge # This is only true if the object was _initialized_ with an override # or if one is assigned later. @has_max_page_size_override = max_page_size != NOT_CONFIGURED @max_page_size = if max_page_size == NOT_CONFIGURED nil else max_page_size end @has_default_page_size_override = default_page_size != NOT_CONFIGURED @default_page_size = if default_page_size == NOT_CONFIGURED nil else default_page_size end @was_authorized_by_scope_items = end |
Instance Attribute Details
#after_value ⇒ Object
Raw access to client-provided values. (max_page_size not applied to first or last.)
36 37 38 |
# File 'lib/graphql/pagination/connection.rb', line 36 def after_value @after_value end |
#arguments ⇒ Hash<Symbol => Object>
Returns The field arguments from the field that returned this connection.
57 58 59 |
# File 'lib/graphql/pagination/connection.rb', line 57 def arguments @arguments end |
#before_value ⇒ Object
Raw access to client-provided values. (max_page_size not applied to first or last.)
36 37 38 |
# File 'lib/graphql/pagination/connection.rb', line 36 def before_value @before_value end |
#context ⇒ GraphQL::Query::Context
22 23 24 |
# File 'lib/graphql/pagination/connection.rb', line 22 def context @context end |
#edge_class ⇒ Class
Returns A wrapper class for edges of this connection.
176 177 178 |
# File 'lib/graphql/pagination/connection.rb', line 176 def edge_class @edge_class end |
#field ⇒ GraphQL::Schema::Field
Returns The field this connection was returned by.
179 180 181 |
# File 'lib/graphql/pagination/connection.rb', line 179 def field @field end |
#first ⇒ Integer?
Returns A clamped first value.
(The underlying instance variable doesn’t have limits on it.)
If neither first nor last is given, but default_page_size is
present, default_page_size is used for first. If default_page_size
is greater than max_page_size, it'll be clamped down to
max_page_size. If default_page_size is nil, use max_page_size`.
145 146 147 148 149 150 151 152 153 |
# File 'lib/graphql/pagination/connection.rb', line 145 def first @first ||= begin capped = limit_pagination_argument(@first_value, max_page_size) if capped.nil? && last.nil? capped = limit_pagination_argument(default_page_size, max_page_size) || max_page_size end capped end end |
#first_value ⇒ Object
Raw access to client-provided values. (max_page_size not applied to first or last.)
36 37 38 |
# File 'lib/graphql/pagination/connection.rb', line 36 def first_value @first_value end |
#items ⇒ Object (readonly)
Returns A list object, from the application. This is the unpaginated value passed into the connection.
19 20 21 |
# File 'lib/graphql/pagination/connection.rb', line 19 def items @items end |
#last ⇒ Integer?
Returns A clamped last value. (The underlying instance variable doesn’t have limits on it).
166 167 168 |
# File 'lib/graphql/pagination/connection.rb', line 166 def last @last ||= limit_pagination_argument(@last_value, max_page_size) end |
#last_value ⇒ Object
Raw access to client-provided values. (max_page_size not applied to first or last.)
36 37 38 |
# File 'lib/graphql/pagination/connection.rb', line 36 def last_value @last_value end |
#parent ⇒ Object
Returns the object this collection belongs to.
33 34 35 |
# File 'lib/graphql/pagination/connection.rb', line 33 def parent @parent end |
#was_authorized_by_scope_items=(value) ⇒ Object (writeonly)
Sets the attribute was_authorized_by_scope_items
97 98 99 |
# File 'lib/graphql/pagination/connection.rb', line 97 def (value) @was_authorized_by_scope_items = value end |
Instance Method Details
#after ⇒ String?
Returns the client-provided cursor. "" is treated as nil.
48 49 50 51 52 53 54 |
# File 'lib/graphql/pagination/connection.rb', line 48 def after if defined?(@after) @after else @after = @after_value == "" ? nil : @after_value end end |
#before ⇒ String?
Returns the client-provided cursor. "" is treated as nil.
39 40 41 42 43 44 45 |
# File 'lib/graphql/pagination/connection.rb', line 39 def before if defined?(@before) @before else @before = @before_value == "" ? nil : @before_value end end |
#cursor_for(item) ⇒ String
Return a cursor for this item.
220 221 222 |
# File 'lib/graphql/pagination/connection.rb', line 220 def cursor_for(item) raise PaginationImplementationMissingError, "Implement #{self.class}#cursor_for(item) to return the cursor for #{item.inspect}" end |
#default_page_size ⇒ Object
125 126 127 128 129 130 131 |
# File 'lib/graphql/pagination/connection.rb', line 125 def default_page_size if @has_default_page_size_override @default_page_size else context.schema.default_page_size end end |
#default_page_size=(new_value) ⇒ Object
120 121 122 123 |
# File 'lib/graphql/pagination/connection.rb', line 120 def default_page_size=(new_value) @has_default_page_size_override = true @default_page_size = new_value end |
#edge_nodes ⇒ Object
use #nodes instead
A dynamic alias for compatibility with Relay::BaseConnection.
188 189 190 |
# File 'lib/graphql/pagination/connection.rb', line 188 def edge_nodes nodes end |
#edges ⇒ Array<Edge>
Returns #nodes, but wrapped with Edge instances.
171 172 173 |
# File 'lib/graphql/pagination/connection.rb', line 171 def edges @edges ||= nodes.map { |n| @edge_class.new(n, self) } end |
#end_cursor ⇒ String
Returns The cursor of the last item in #nodes.
213 214 215 |
# File 'lib/graphql/pagination/connection.rb', line 213 def end_cursor nodes.last && cursor_for(nodes.last) end |
#has_default_page_size_override? ⇒ Boolean
133 134 135 |
# File 'lib/graphql/pagination/connection.rb', line 133 def has_default_page_size_override? @has_default_page_size_override end |
#has_max_page_size_override? ⇒ Boolean
116 117 118 |
# File 'lib/graphql/pagination/connection.rb', line 116 def has_max_page_size_override? @has_max_page_size_override end |
#has_next_page ⇒ Boolean
Returns True if there are more items after this page.
198 199 200 |
# File 'lib/graphql/pagination/connection.rb', line 198 def has_next_page raise PaginationImplementationMissingError, "Implement #{self.class}#has_next_page to return the next-page check" end |
#has_previous_page ⇒ Boolean
Returns True if there were items before these items.
203 204 205 |
# File 'lib/graphql/pagination/connection.rb', line 203 def has_previous_page raise PaginationImplementationMissingError, "Implement #{self.class}#has_previous_page to return the previous-page check" end |
#max_page_size ⇒ Object
108 109 110 111 112 113 114 |
# File 'lib/graphql/pagination/connection.rb', line 108 def max_page_size if @has_max_page_size_override @max_page_size else context.schema.default_max_page_size end end |
#max_page_size=(new_value) ⇒ Object
103 104 105 106 |
# File 'lib/graphql/pagination/connection.rb', line 103 def max_page_size=(new_value) @has_max_page_size_override = true @max_page_size = new_value end |
#nodes ⇒ Array<Object>
Returns A slice of #items, constrained by @first_value/@after_value/@last_value/@before_value.
182 183 184 |
# File 'lib/graphql/pagination/connection.rb', line 182 def nodes raise PaginationImplementationMissingError, "Implement #{self.class}#nodes to paginate `@items`" end |
#page_info ⇒ Object
The connection object itself implements PageInfo fields
193 194 195 |
# File 'lib/graphql/pagination/connection.rb', line 193 def page_info self end |
#range_add_edge(item) ⇒ Edge
This is called by Relay::RangeAdd – it can be overridden
when item needs some modifications based on this connection’s state.
160 161 162 |
# File 'lib/graphql/pagination/connection.rb', line 160 def range_add_edge(item) edge_class.new(item, self) end |
#start_cursor ⇒ String
Returns The cursor of the first item in #nodes.
208 209 210 |
# File 'lib/graphql/pagination/connection.rb', line 208 def start_cursor nodes.first && cursor_for(nodes.first) end |
#was_authorized_by_scope_items? ⇒ Boolean
99 100 101 |
# File 'lib/graphql/pagination/connection.rb', line 99 def @was_authorized_by_scope_items end |