Skip to main content

Overview

The Rails::GraphQL::Request class processes GraphQL operations including queries, mutations, and subscriptions. It handles document parsing, validation, execution, and response formatting. Namespace: Rails::GraphQL Extends: ActiveSupport::Autoload

Constructor

initialize

schema
Schema
The schema to execute against
namespace
Symbol
default:":base"
The namespace to use if schema not provided
request = Rails::GraphQL::Request.new(schema)
# or
request = Rails::GraphQL::Request.new(namespace: :api)

Class Methods

execute

Shortcut to initialize, set context, and execute a request.
document
String
required
The GraphQL query document
schema
Schema
The schema to execute against
namespace
Symbol
default:":base"
Namespace if schema not provided
context
Hash
default:"{}"
Context data available during execution
variables
Hash
Query variables
args
Hash
Alias for variables
operation_name
String
Name of operation to execute (if document has multiple)
as
Symbol
default:":string"
Response format (:string, :hash, :json, :object)
Returns: Formatted response
result = Rails::GraphQL::Request.execute(
  query,
  schema: ApiSchema,
  variables: { id: 1 },
  context: { current_user: user }
)
Alias: perform

compile

Compile a GraphQL document to cached format.
document
String
required
The GraphQL query document
schema
Schema
The schema to compile against
namespace
Symbol
default:":base"
Namespace if schema not provided
compress
Boolean
default:"true"
Whether to compress the compiled output
Returns: String - Serialized compiled document
compiled = Rails::GraphQL::Request.compile(query, schema: ApiSchema)

valid?

Validate a GraphQL document.
document
String
required
The GraphQL query document
schema
Schema
The schema to validate against
namespace
Symbol
default:":base"
Namespace if schema not provided
Returns: Boolean
if Rails::GraphQL::Request.valid?(query, schema: ApiSchema)
  # Execute query
end

Instance Attributes

args
OpenStruct
Query variables/arguments
origin
Controller | Channel
The controller or channel that originated the request
errors
Errors
Collection of errors encountered during execution
fragments
Hash
Named fragments defined in the document
operations
Hash
Operations defined in the document
response
Object
The response collector object
schema
Schema
The schema being executed
stack
Array
Execution stack for error reporting
strategy
Strategy
Execution strategy (Query, Mutation, Subscription)
document
Token
Parsed document token
operation_name
String
Name of the operation being executed
subscriptions
Hash
Active subscriptions created during execution
Aliases:
  • argumentsargs
  • controllerorigin
  • channelorigin

Instance Methods

execute

Execute a GraphQL document.
document
String
required
The GraphQL query document
as
Symbol
Response format (:string, :hash, :json, :object)
variables
Hash
Query variables
args
Hash
Alias for variables
operation_name
String
Operation name to execute
origin
Controller | Channel
Originating controller or channel
compiled
Boolean
default:"false"
Whether document is pre-compiled
hash
String
Cache key for storing/retrieving compiled document
data_for
Hash
Prepared data for specific fields
Returns: Formatted response
request = Rails::GraphQL::Request.new(schema)
result = request.execute(
  query,
  variables: { id: 1 },
  as: :json
)
Alias: perform

compile

Compile a document for caching.
document
String
required
The GraphQL query document
compress
Boolean
default:"true"
Whether to compress the output
Returns: String - Serialized compiled document
request = Rails::GraphQL::Request.new(schema)
compiled = request.compile(query)

valid?

Check if a document is valid.
document
String
required
The GraphQL query document
Returns: Boolean
request = Rails::GraphQL::Request.new(schema)
if request.valid?(query)
  request.execute(query)
end

Context Management

context

Get the request context. Returns: OpenStruct (frozen)
request.context.current_user

context=

Set the request context.
data
Hash
required
Context data
request.context = { current_user: user, locale: 'en' }

extensions

Get the extensions hash for adding metadata to response. Returns: Hash
request.extensions[:timing] = { started_at: Time.current }

Prepared Data

prepare_data_for

Prepare data for a specific field to avoid N+1 queries.
field
Field | String
required
The field to prepare data for
value
Any
required
The prepared data
options
Hash
Additional options
request.prepare_data_for(:posts, Post.all.to_a)

import_prepared_data

Import multiple prepared data entries.
prepared_data
Hash
required
Hash of field names/objects to prepared data
request.import_prepared_data(
  posts: Post.all.to_a,
  users: User.all.to_a
)

prepared_data_for

Retrieve prepared data for a field.
field
Field
required
The field to get data for
Returns: Prepared data or nil
data = request.prepared_data_for(field)

prepared_data_for?

Check if prepared data exists for a field.
field
Field
required
The field to check
Returns: Boolean
if request.prepared_data_for?(field)
  # Use prepared data
end

Error Reporting

report_error

Report an error with the current execution context.
message
String
required
Error message
path
Array
Path to the field (auto-generated from stack if not provided)
locations
Array
Source locations
extensions
Hash
Additional error metadata
Returns: nil
request.report_error('User not found', extensions: { code: 'NOT_FOUND' })

report_node_error

Report an error on a specific AST node.
message
String
required
Error message
node
Token
required
AST node where error occurred
extensions
Hash
Additional error metadata
request.report_node_error('Invalid argument', node)

exception_to_error

Convert an exception to a GraphQL error.
exception
Exception
required
The exception to convert
node
Token
required
AST node where exception occurred
message
String
Custom error message (defaults to exception message)
request.exception_to_error(error, node, message: 'Failed to resolve field')

rescue_with_handler

Use schema handlers for caught exceptions.
exception
Exception
required
The exception to handle
extra
Hash
Additional context data
request.rescue_with_handler(exception, field: current_field)

location_of

Get the source location of an AST node.
node
Token | Component
required
The node to get location for
Returns: Array<Hash> - Start and end locations
location = request.location_of(node)
# => [{ "line" => 1, "column" => 5 }, { "line" => 1, "column" => 15 }]

Cache Management

cache

Get or initialize a cache entry.
key
Any
required
Cache key
init_value
Any
Initial value if not present
block
Block
Block to compute initial value
Returns: Cached value
request.cache(:user_loader) { UserLoader.new }

nested_cache

Get or initialize a nested cache entry.
key
Any
required
Outer cache key
sub_key
Any
required
Inner cache key
block
Block
required
Block to compute value if not present
Returns: Cached value
value = request.nested_cache(:loaders, :user) { UserLoader.new }

valid_cache?

Check if the cached operation is still valid. Returns: Boolean
request.valid_cache? # => true

Stack Management

stacked

Execute a block with an object added to the execution stack.
object
Any
required
Object to add to stack
block
Block
required
Block to execute
request.stacked(field) do
  # Field is now on the stack for error reporting
  resolve_field
end

stack_to_path

Convert the current execution stack to an error path. Returns: Array
request.stack_to_path # => ["user", "posts", 0, "title"]

Type Resolution

find_type!

Find a type in the schema.
type
Symbol | String
required
Type name
Returns: Type class Raises: Exception if not found Alias: find_type
user_type = request.find_type!(:User)

Subscriptions

subscriptions?

Check if any subscriptions were added during execution. Returns: Boolean
request.subscriptions? # => true

Query Helpers

action_name

Get the action name from the origin controller. Returns: String or nil
request.action_name # => "graphql"

Response Formats


Example Usage

Basic Query Execution

query = <<~GRAPHQL
  query GetUser($id: ID!) {
    user(id: $id) {
      id
      name
      email
    }
  }
GRAPHQL

result = Rails::GraphQL::Request.execute(
  query,
  schema: ApiSchema,
  variables: { id: '123' },
  context: { current_user: current_user }
)

puts result
# => {"data":{"user":{"id":"123","name":"John Doe","email":"[email protected]"}}}

With Prepared Data (N+1 Prevention)

request = Rails::GraphQL::Request.new(ApiSchema)
request.context = { current_user: user }

# Prepare data to avoid N+1 queries
users = User.includes(:posts).all
request.prepare_data_for(:users, users)

result = request.execute(query, as: :hash)

Compiled Query Execution

# Compile once
compiled = Rails::GraphQL::Request.compile(query, schema: ApiSchema)

# Store in cache
Rails.cache.write("query:#{query_hash}", compiled)

# Execute many times
compiled = Rails.cache.read("query:#{query_hash}")
result = Rails::GraphQL::Request.execute(
  compiled,
  schema: ApiSchema,
  compiled: true,
  variables: { id: '123' }
)

Error Handling

class ApiSchema < Rails::GraphQL::Schema
  rescue_from(ActiveRecord::RecordNotFound) do |error|
    report_error(
      'Record not found',
      extensions: { code: 'NOT_FOUND' }
    )
  end

  rescue_from(ActiveRecord::RecordInvalid) do |error|
    report_error(
      error.record.errors.full_messages.join(', '),
      extensions: { code: 'VALIDATION_ERROR' }
    )
  end
end

Custom Context

request = Rails::GraphQL::Request.new(ApiSchema)
request.context = {
  current_user: current_user,
  ip_address: request.remote_ip,
  locale: I18n.locale,
  abilities: current_user.abilities
}

result = request.execute(query)

# Access in resolvers
class Query < Rails::GraphQL::Type::Object
  field :current_user, :User do
    def resolve
      request.context.current_user
    end
  end
end

Build docs developers (and LLMs) love