Class: GraphQL::Pagination::Connection

Inherits:
Object
  • Object
show all
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

ArrayConnection, RelationConnection

Defined Under Namespace

Classes: Edge, PaginationImplementationMissingError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(items, context: nil, first: nil, after: nil, max_page_size: :not_given, last: nil, before: nil) ⇒ Connection


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/graphql/pagination/connection.rb', line 57

def initialize(items, context: nil, first: nil, after: nil, max_page_size: :not_given, last: nil, before: nil)
  @items = items
  @context = context
  @first_value = first
  @after_value = after
  @last_value = last
  @before_value = before

  # 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_given
  @max_page_size = if max_page_size == :not_given
    nil
  else
    max_page_size
  end
end

Instance Attribute Details

#after_valueObject

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_valueObject

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

#contextGraphQL::Query::Context


27
28
29
# File 'lib/graphql/pagination/connection.rb', line 27

def context
  @context
end

#firstInteger?


97
98
99
100
101
102
103
104
105
# File 'lib/graphql/pagination/connection.rb', line 97

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_valueObject

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

#itemsObject (readonly)


24
25
26
# File 'lib/graphql/pagination/connection.rb', line 24

def items
  @items
end

#lastInteger?


109
110
111
# File 'lib/graphql/pagination/connection.rb', line 109

def last
  @last ||= limit_pagination_argument(@last_value, max_page_size)
end

#last_valueObject

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

Class Method Details

.edge_classClass


19
20
21
# File 'lib/graphql/pagination/connection.rb', line 19

def self.edge_class
  self::Edge
end

Instance Method Details

#afterString?


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

#beforeString?


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.


157
158
159
# File 'lib/graphql/pagination/connection.rb', line 157

def cursor_for(item)
  raise PaginationImplementationMissingError, "Implement #{self.class}#cursor_for(item) to return the cursor for #{item.inspect}"
end

#edge_nodesObject

Deprecated.

use #nodes instead

A dynamic alias for compatibility with Relay::BaseConnection.


125
126
127
# File 'lib/graphql/pagination/connection.rb', line 125

def edge_nodes
  nodes
end

#edgesArray<Edge>


114
115
116
# File 'lib/graphql/pagination/connection.rb', line 114

def edges
  @edges ||= nodes.map { |n| self.class.edge_class.new(n, self) }
end

#end_cursorString


150
151
152
# File 'lib/graphql/pagination/connection.rb', line 150

def end_cursor
  nodes.last && cursor_for(nodes.last)
end

#has_max_page_size_override?Boolean


88
89
90
# File 'lib/graphql/pagination/connection.rb', line 88

def has_max_page_size_override?
  @has_max_page_size_override
end

#has_next_pageBoolean

Returns True if there are more items after this page.


135
136
137
# File 'lib/graphql/pagination/connection.rb', line 135

def has_next_page
  raise PaginationImplementationMissingError, "Implement #{self.class}#has_next_page to return the next-page check"
end

#has_previous_pageBoolean

Returns True if there were items before these items.


140
141
142
# File 'lib/graphql/pagination/connection.rb', line 140

def has_previous_page
  raise PaginationImplementationMissingError, "Implement #{self.class}#has_previous_page to return the previous-page check"
end

#max_page_sizeObject


80
81
82
83
84
85
86
# File 'lib/graphql/pagination/connection.rb', line 80

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


75
76
77
78
# File 'lib/graphql/pagination/connection.rb', line 75

def max_page_size=(new_value)
  @has_max_page_size_override = true
  @max_page_size = new_value
end

#nodesArray<Object>

Returns A slice of #items, constrained by @first_value/@after_value/@last_value/@before_value.


119
120
121
# File 'lib/graphql/pagination/connection.rb', line 119

def nodes
  raise PaginationImplementationMissingError, "Implement #{self.class}#nodes to paginate `@items`"
end

#page_infoObject

The connection object itself implements PageInfo fields


130
131
132
# File 'lib/graphql/pagination/connection.rb', line 130

def page_info
  self
end

#start_cursorString


145
146
147
# File 'lib/graphql/pagination/connection.rb', line 145

def start_cursor
  nodes.first && cursor_for(nodes.first)
end