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.
-
#before_value ⇒ Object
Raw access to client-provided values.
-
#context ⇒ GraphQL::Query::Context
-
#first ⇒ Integer?
A clamped
first
value. -
#first_value ⇒ Object
Raw access to client-provided values.
-
#items ⇒ Object
readonly
A list object, from the application.
-
#last ⇒ Integer?
A clamped
last
value. -
#last_value ⇒ Object
Raw access to client-provided values.
-
#max_page_size ⇒ Object
Class Method Summary collapse
-
.edge_class ⇒ Class
The class to use for wrapping items as
edges { ... }
.
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.
-
#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_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, context: nil, first: nil, after: nil, max_page_size: nil, last: nil, before: nil) ⇒ Connection
constructor
A new instance of Connection.
-
#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
PageInfo
fields. -
#start_cursor ⇒ String
The cursor of the first item in #nodes.
Constructor Details
#initialize(items, context: nil, first: nil, after: nil, max_page_size: nil, last: nil, before: nil) ⇒ Connection
Returns a new instance of Connection.
57 58 59 60 61 62 63 64 65 |
# File 'lib/graphql/pagination/connection.rb', line 57 def initialize(items, context: nil, first: nil, after: nil, max_page_size: nil, last: nil, before: nil) @items = items @context = context @first_value = first @after_value = after @last_value = last @before_value = before @max_page_size = max_page_size end |
Instance Attribute Details
#after_value ⇒ Object
Raw access to client-provided values. (max_page_size
not applied to first or last.)
30 31 32 |
# File 'lib/graphql/pagination/connection.rb', line 30 def after_value @after_value end |
#before_value ⇒ Object
Raw access to client-provided values. (max_page_size
not applied to first or last.)
30 31 32 |
# File 'lib/graphql/pagination/connection.rb', line 30 def before_value @before_value end |
#context ⇒ GraphQL::Query::Context
27 28 29 |
# File 'lib/graphql/pagination/connection.rb', line 27 def context @context 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 max_page_size
is present, max_page_size is used for first.
77 78 79 80 81 82 83 84 85 |
# File 'lib/graphql/pagination/connection.rb', line 77 def first @first ||= begin capped = limit_pagination_argument(@first_value, max_page_size) if capped.nil? && last.nil? capped = 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.)
30 31 32 |
# File 'lib/graphql/pagination/connection.rb', line 30 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.
24 25 26 |
# File 'lib/graphql/pagination/connection.rb', line 24 def items @items end |
#last ⇒ Integer?
Returns A clamped last
value. (The underlying instance variable doesn’t have limits on it).
89 90 91 |
# File 'lib/graphql/pagination/connection.rb', line 89 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.)
30 31 32 |
# File 'lib/graphql/pagination/connection.rb', line 30 def last_value @last_value end |
#max_page_size ⇒ Object
68 69 70 |
# File 'lib/graphql/pagination/connection.rb', line 68 def max_page_size @max_page_size ||= context.schema.default_max_page_size end |
Class Method Details
.edge_class ⇒ Class
Returns The class to use for wrapping items as edges { ... }
. Defaults to Connection::Edge
.
19 20 21 |
# File 'lib/graphql/pagination/connection.rb', line 19 def self.edge_class self::Edge end |
Instance Method Details
#after ⇒ String?
Returns the client-provided cursor. ""
is treated as nil
.
42 43 44 45 46 47 48 |
# File 'lib/graphql/pagination/connection.rb', line 42 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
.
33 34 35 36 37 38 39 |
# File 'lib/graphql/pagination/connection.rb', line 33 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.
137 138 139 |
# File 'lib/graphql/pagination/connection.rb', line 137 def cursor_for(item) raise PaginationImplementationMissingError, "Implement #{self.class}#cursor_for(item) to return the cursor for #{item.inspect}" end |
#edge_nodes ⇒ Object
use #nodes instead
A dynamic alias for compatibility with Relay::BaseConnection.
105 106 107 |
# File 'lib/graphql/pagination/connection.rb', line 105 def edge_nodes nodes end |
#edges ⇒ Array<Edge>
Returns #nodes, but wrapped with Edge instances.
94 95 96 |
# File 'lib/graphql/pagination/connection.rb', line 94 def edges @edges ||= nodes.map { |n| self.class.edge_class.new(n, self) } end |
#end_cursor ⇒ String
Returns The cursor of the last item in #nodes.
130 131 132 |
# File 'lib/graphql/pagination/connection.rb', line 130 def end_cursor nodes.last && cursor_for(nodes.last) end |
#has_next_page ⇒ Boolean
Returns True if there are more items after this page.
115 116 117 |
# File 'lib/graphql/pagination/connection.rb', line 115 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.
120 121 122 |
# File 'lib/graphql/pagination/connection.rb', line 120 def has_previous_page raise PaginationImplementationMissingError, "Implement #{self.class}#has_previous_page to return the previous-page check" end |
#nodes ⇒ Array<Object>
Returns A slice of #items, constrained by @first_value/@after_value/@last_value/@before_value.
99 100 101 |
# File 'lib/graphql/pagination/connection.rb', line 99 def nodes raise PaginationImplementationMissingError, "Implement #{self.class}#nodes to paginate `@items`" end |
#page_info ⇒ Object
The connection object itself implements PageInfo
fields
110 111 112 |
# File 'lib/graphql/pagination/connection.rb', line 110 def page_info self end |
#start_cursor ⇒ String
Returns The cursor of the first item in #nodes.
125 126 127 |
# File 'lib/graphql/pagination/connection.rb', line 125 def start_cursor nodes.first && cursor_for(nodes.first) end |