class GraphQL::Pagination::Connection
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).
Attributes
Raw access to client-provided values. (max_page_size not applied to first or last.)
Returns
-
Hash<Symbol => Object>— The field arguments from the field that returned this connection
Raw access to client-provided values. (max_page_size not applied to first or last.)
Returns
Returns
-
Class— A wrapper class for edges of this connection
Returns
-
GraphQL::Schema::Field— The field this connection was returned by
Raw access to client-provided values. (max_page_size not applied to first or last.)
Returns
-
Object— A list object, from the application. This is the unpaginated value passed into the connection.
Raw access to client-provided values. (max_page_size not applied to first or last.)
Returns
-
GraphQL::Execution::LookaheadSelections on this connection, set by connection fields
Returns
-
Object— the object this collection belongs to
Public Class Methods
# File lib/graphql/pagination/connection.rb, line 107 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.const_get(: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 = detect_was_authorized_by_scope_items end
Parameters
-
items(Object) — some unpaginated collection item, like anArrayorActiveRecord::Relation -
context(Query::Context) -
parent(Object) — The object this collection belongs to -
first(Integer, nil) — The limit parameter from the client, if it provided one -
after(String, nil) — A cursor for pagination, if the client provided one -
last(Integer, nil) — Limit parameter from the client, if provided -
before(String, nil) — A cursor for pagination, if the client provided one. -
arguments(Hash) — The arguments to the field that returned the collection wrapped by this connection -
max_page_size(Integer, nil) — A configured value to cap the result size. Applied asfirstif neither first or last are given and nodefault_page_sizeis set. -
default_page_size(Integer, nil) — A configured value to determine the result size when neither first or last are given.
Public Instance Methods
Source
# File lib/graphql/pagination/connection.rb, line 79 def after if defined?(@after) @after else @after = @after_value == "" ? nil : @after_value end end
Returns
-
String, nil— the client-provided cursor.""is treated asnil.
Source
# File lib/graphql/pagination/connection.rb, line 65 def before if defined?(@before) @before else @before = @before_value == "" ? nil : @before_value end end
Returns
-
String, nil— the client-provided cursor.""is treated asnil.
Source
# File lib/graphql/pagination/connection.rb, line 43 def context=(new_ctx) @context = new_ctx if @was_authorized_by_scope_items.nil? @was_authorized_by_scope_items = detect_was_authorized_by_scope_items end @context end
# File lib/graphql/pagination/connection.rb, line 322 def cursor_for(item) raise PaginationImplementationMissingError, "Implement #{self.class}#cursor_for(item) to return the cursor for #{item.inspect}" end
Source
# File lib/graphql/pagination/connection.rb, line 163 def default_page_size if @has_default_page_size_override @default_page_size else context.schema.default_page_size end end
# File lib/graphql/pagination/connection.rb, line 158 def default_page_size=(new_value) @has_default_page_size_override = true @default_page_size = new_value end
Source
# File lib/graphql/pagination/connection.rb, line 261 def edge_nodes nodes end
A dynamic alias for compatibility with GraphQL::Types::Relay::BaseConnection. Deprecated: use nodes instead
Source
# File lib/graphql/pagination/connection.rb, line 226 def edges @edges ||= nodes.each_with_index.map do |n, index| edge = @edge_class.new(n, self) edge.graphql_connection_position = index edge end end
Source
# File lib/graphql/pagination/connection.rb, line 306 def end_cursor nodes.last && cursor_for_position(nodes.last, nodes.length - 1) end
Returns
-
String— The cursor of the last item innodes
Source
# File lib/graphql/pagination/connection.rb, line 182 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
Returns
-
Integer, nil— A clampedfirstvalue. (The underlying instance variable doesn’t have limits on it.) If neitherfirstnorlastis given, butdefault_page_sizeis present,default_page_sizeis used for first. Ifdefault_page_sizeis greater thanmax_page_size``, it'll be clamped down tomax_page_size. Ifdefault_page_sizeis nil, usemax_page_size`.
# File lib/graphql/pagination/connection.rb, line 171 def has_default_page_size_override? @has_default_page_size_override end
# File lib/graphql/pagination/connection.rb, line 154 def has_max_page_size_override? @has_max_page_size_override end
Source
# File lib/graphql/pagination/connection.rb, line 276 def has_next_page raise PaginationImplementationMissingError, "Implement #{self.class}#has_next_page to return the next-page check" end
Returns
-
Boolean— True if there are more items after this page
Source
# File lib/graphql/pagination/connection.rb, line 286 def has_previous_page raise PaginationImplementationMissingError, "Implement #{self.class}#has_previous_page to return the previous-page check" end
Returns
-
Boolean— True if there were items before these items
Source
# File lib/graphql/pagination/connection.rb, line 216 def last @last ||= limit_pagination_argument(@last_value, max_page_size) end
Returns
-
Integer, nil— A clampedlastvalue. (The underlying instance variable doesn’t have limits on it)
Source
# File lib/graphql/pagination/connection.rb, line 146 def max_page_size if @has_max_page_size_override @max_page_size else context.schema.default_max_page_size end end
Source
# File lib/graphql/pagination/connection.rb, line 141 def max_page_size=(new_value) @has_max_page_size_override = true @max_page_size = new_value end
Source
# File lib/graphql/pagination/connection.rb, line 255 def nodes raise PaginationImplementationMissingError, "Implement #{self.class}#nodes to paginate `@items`" end
Returns
-
Array<Object>— A slice ofitems, constrained by@first_value/@after_value/@last_value/@before_value
Source
# File lib/graphql/pagination/connection.rb, line 266 def page_info self end
The connection object itself implements PageInfo fields
# File lib/graphql/pagination/connection.rb, line 205 def range_add_edge(item) edge_class.new(item, self) end
This is called by Relay::RangeAdd – it can be overridden when item needs some modifications based on this connection’s state.
Parameters
-
item(Object) — An item newly added toitems
Returns
Source
# File lib/graphql/pagination/connection.rb, line 296 def start_cursor nodes.first && cursor_for_position(nodes.first, 0) end
Returns
-
String— The cursor of the first item innodes