Table of Contents


This page will explore more advanced features of requests. It would be best if you started from there before reading this content.


Request strategies are the actual classes responsible for handling the last three phases of a request: organize, prepare, and resolve. They all inherit from the base Strategy class, and the request will go over all the available strategies to rank the best one to execute a document.

As of now, there are only two strategies:

Rank 10
Will run each phase once per operation, but only if there are no mutation operations.
Rank 1
Will perform one operation at a time, which is the default behavior.

You can implement your own strategy and override any of the existing methods to fulfill your application’s needs. Just remember to add them to the request_strategies setting.

Prepared Data

Prepared data allows you to inject data into any field before a request is kicked off. With prepared data, you can stub results for testing and deliver fast subscriptions.

To prepare data for a field, you need the field instance or a reference to it, the prepared value, and a conditional indicator for repetition.

def prepare_data_for(field, value, repeat: 1)


You can use any searching method to grab the instance of the field you are preparing the data for. But, you can also pass a reference as "type"."field", for example:

# Using the Type Map
''          # => GraphQL::User[:id]
# Using the schema
'query.users'      # => GraphQL::AppSchema[:query][:users]


The value has some special behaviors depending if it was provided an array and if the field resolves to an array. The table below shows the prepared value each time the field is resolved:

value \ field array? !array?
array? next array next value
!array? array with value same value

The example below shows a case where addresses can be resolved twice, each time with a different list of values.

prepare_data_for('User.addresses', [[ 1), 2),
], [ 3), 4),

Note Calling prepare_data_for subsequent times with the same field will append the value to the prepared data value.


The repeat argument indicates how many times the field can be resolved till it exhausts the prepared data. The example below will result in a cycle between 1 and 2.

prepare_data_for('', [1, 2], repeat: true)

It accepts a number for the number of repetitions, true to always repeat, or false to never repeat. Here is some alias values:


Data Stack

The data stack is similar to the field stack when traversing the document, but it refers to the data assigned to each field during the prepare and resolve phases.

You can access it via the strategy.context or event.resolver.


There are several different ways to access the data in the stack:

Returns the last item of the stack.
Returns the second to last item of the stack.
Returns all the values from the parent downwards.
Returns a value at a specific position
0 is the last.

Now, by calling resolver.current, you will get an extraordinary object. You can think of it as a loose reference to the last value of the stack. This means that if the value changed to something else, every other place that called current will now have the updated reference to the new value.

This ability is crucial for events and request processing because they need a “value by reference” for the result of resolved fields. It is implemented in a way that you probably won’t ever notice it.


The data stack allows changing only the current value, never any of the ancestors. To perform such change, you can call either resolver.override_value(value) or resolver.current_value = value.


Events provide a couple of shortcuts to access data stack:

Read the current value
Same as above
event.current_value = value
Write the current value

Read more about request events.


This gem supports caching documents after they have been organized. Any subsequent request using a cached document will recover the state where it was after that phase was completed and move forward with the next two phases.

This is an implementation based on Apollo’s Persisted Queries. You can use the query_cache_key controller method or the gql_query_cache_key channel method to correctly set up the incoming cache key and version and leave the request to do the rest.

Everything cached by a request will be saved using the schema cache configuration.

If the Type Map version changed, then the document will be reorganized.


Important This is an experimental feature. More will be added to it soon.

Compiling is almost the same as caching. The difference lies in the fact that the request will return the cache string instead of saving it somewhere.

This is part of a future feature named strict mode, where you would compile all the documents that your application accepts, store them as files, or on a database, or even on the cache, and only use a unique identifier to reference such documents.

As of now, requests can compile a document, and even compress it, and run a compiled document when it is informed that the provided document is compiled: true.