Class: ElasticGraph::GraphQL::DecodedCursor
- Inherits:
-
Object
- Object
- ElasticGraph::GraphQL::DecodedCursor
- Defined in:
- lib/elastic_graph/graphql/decoded_cursor.rb
Overview
Provides the in-memory representation of a cursor after it has been decoded, as a simple hash of sort values.
The datastore’s ‘search_after` pagination uses an array of values (which represent values of the fields you are sorting by). A cursor returned when we applied one sort is generally not valid when we apply a completely different sort. To ensure we can detect this, the encoder encodes a hash of sort fields and values, ensuring each value in the cursor is properly labeled with what field it came from. This allows us to detect situations where the client uses a cursor with a completely different sort applied, while allowing some minor variation in the sort. The following are still allowed:
- Changing the direction of the sort (from `asc` to `desc` or vice-versa)
- Re-ordering the sort (e.g. changing from `[amount_money_DESC, created_at_ASC]`
to `[created_at_ASC, amount_money_DESC]`
- Removing fields from the sort (e.g. changing from `[amount_money_DESC, created_at_ASC]`
to `[amount_money_DESC]`) -- but adding fields is not allowed
While we don’t necessarily recommend clients change these things between pagination requests (the behavior may be surprising to the user), there is no ambiguity in how to support them, and we do not feel like it makes sense to restrict it at this point.
Defined Under Namespace
Classes: Factory
Constant Summary collapse
- SINGLETON =
A special cursor instance for when we need a cursor but have only a static collection of a single element without any sort of key we can encode.
new({}).tap do |sc| # Ensure the special string value is returned even though our `sort_values` are empty. def sc.encode SINGLETON_CURSOR end end
Class Method Summary collapse
-
.decode!(string) ⇒ Object
Tries to decode the given string cursor, raising an ‘InvalidCursorError` if it’s invalid.
-
.try_decode(string) ⇒ Object
Tries to decode the given string cursor, returning ‘nil` if it is invalid.
Instance Method Summary collapse
-
#encode ⇒ Object
Encodes the cursor to a string using JSON and Base64 encoding.
Class Method Details
.decode!(string) ⇒ Object
Tries to decode the given string cursor, raising an ‘InvalidCursorError` if it’s invalid.
47 48 49 50 51 52 53 |
# File 'lib/elastic_graph/graphql/decoded_cursor.rb', line 47 def self.decode!(string) return SINGLETON if string == SINGLETON_CURSOR json = ::Base64.urlsafe_decode64(string) new(::JSON.parse(json)) rescue ::ArgumentError, ::JSON::ParserError raise InvalidCursorError, "`#{string}` is an invalid cursor." end |
.try_decode(string) ⇒ Object
Tries to decode the given string cursor, returning ‘nil` if it is invalid.
40 41 42 43 44 |
# File 'lib/elastic_graph/graphql/decoded_cursor.rb', line 40 def self.try_decode(string) decode!(string) rescue InvalidCursorError nil end |
Instance Method Details
#encode ⇒ Object
Encodes the cursor to a string using JSON and Base64 encoding.
56 57 58 59 60 61 |
# File 'lib/elastic_graph/graphql/decoded_cursor.rb', line 56 def encode @encode ||= begin json = ::JSON.fast_generate(sort_values) ::Base64.urlsafe_encode64(json, padding: false) end end |