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.
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
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 = 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>
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
174 175 176 |
# File 'lib/graphql/pagination/connection.rb', line 174 def edge_class @edge_class end |
#field ⇒ GraphQL::Schema::Field
177 178 179 |
# File 'lib/graphql/pagination/connection.rb', line 177 def field @field end |
#first ⇒ Integer?
143 144 145 146 147 148 149 150 151 |
# File 'lib/graphql/pagination/connection.rb', line 143 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)
19 20 21 |
# File 'lib/graphql/pagination/connection.rb', line 19 def items @items end |
#last ⇒ Integer?
164 165 166 |
# File 'lib/graphql/pagination/connection.rb', line 164 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
33 34 35 |
# File 'lib/graphql/pagination/connection.rb', line 33 def parent @parent end |
Instance Method Details
#after ⇒ String?
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?
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.
218 219 220 |
# File 'lib/graphql/pagination/connection.rb', line 218 def cursor_for(item) raise PaginationImplementationMissingError, "Implement #{self.class}#cursor_for(item) to return the cursor for #{item.inspect}" end |
#default_page_size ⇒ Object
123 124 125 126 127 128 129 |
# File 'lib/graphql/pagination/connection.rb', line 123 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
118 119 120 121 |
# File 'lib/graphql/pagination/connection.rb', line 118 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.
186 187 188 |
# File 'lib/graphql/pagination/connection.rb', line 186 def edge_nodes nodes end |
#edges ⇒ Array<Edge>
169 170 171 |
# File 'lib/graphql/pagination/connection.rb', line 169 def edges @edges ||= nodes.map { |n| @edge_class.new(n, self) } end |
#end_cursor ⇒ String
211 212 213 |
# File 'lib/graphql/pagination/connection.rb', line 211 def end_cursor nodes.last && cursor_for(nodes.last) end |
#has_default_page_size_override? ⇒ Boolean
131 132 133 |
# File 'lib/graphql/pagination/connection.rb', line 131 def has_default_page_size_override? @has_default_page_size_override end |
#has_max_page_size_override? ⇒ Boolean
114 115 116 |
# File 'lib/graphql/pagination/connection.rb', line 114 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.
196 197 198 |
# File 'lib/graphql/pagination/connection.rb', line 196 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.
201 202 203 |
# File 'lib/graphql/pagination/connection.rb', line 201 def has_previous_page raise PaginationImplementationMissingError, "Implement #{self.class}#has_previous_page to return the previous-page check" end |
#max_page_size ⇒ Object
106 107 108 109 110 111 112 |
# File 'lib/graphql/pagination/connection.rb', line 106 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
101 102 103 104 |
# File 'lib/graphql/pagination/connection.rb', line 101 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.
180 181 182 |
# File 'lib/graphql/pagination/connection.rb', line 180 def nodes raise PaginationImplementationMissingError, "Implement #{self.class}#nodes to paginate `@items`" end |
#page_info ⇒ Object
The connection object itself implements PageInfo fields
191 192 193 |
# File 'lib/graphql/pagination/connection.rb', line 191 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.
158 159 160 |
# File 'lib/graphql/pagination/connection.rb', line 158 def range_add_edge(item) edge_class.new(item, self) end |
#start_cursor ⇒ String
206 207 208 |
# File 'lib/graphql/pagination/connection.rb', line 206 def start_cursor nodes.first && cursor_for(nodes.first) end |
#was_authorized_by_scope_items? ⇒ Boolean
97 98 99 |
# File 'lib/graphql/pagination/connection.rb', line 97 def end |