Class: GraphQL::RootCall

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/root_call.rb

Overview

Every query begins with a root call. It might find data or mutate data and return some results.

A root call should:

  • declare any arguments with RootCall.argument, or declare ‘argument.none`

  • declare returns with return

  • implement #execute! to take those arguments and return values

Examples:

FindPostCall < GraphQL::RootCall
  argument.number(:ids, any_number: true)
  returns :post

  def execute!(*ids)
    ids.map { |id| Post.find(id) }
  end
end
CreateCommentCall < GraphQL::RootCall
  argument.number(:post_id)
  argument.object(:comment)
  returns :post, :comment

  def execute!(post_id, comment)
    post = Post.find(post_id)
    new_comment = post.comments.create!(comment)
    {
      comment: new_comment,
      post: post,
    }
  end
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(query:, syntax_arguments:) ⇒ RootCall

Validates arguments against declared arguments



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/graphql/root_call.rb', line 39

def initialize(query:, syntax_arguments:)
  @query = query

  raise "#{self.class.name} must declare arguments" unless self.class.arguments
  @arguments = syntax_arguments.each_with_index.map do |syntax_arg, idx|

    value = if syntax_arg[0] == "<"
        query.get_variable(syntax_arg).json_string
      else
        syntax_arg
      end

    typecast(idx, value)
  end
end

Instance Attribute Details

#argumentsObject (readonly)

Returns the value of attribute arguments.



36
37
38
# File 'lib/graphql/root_call.rb', line 36

def arguments
  @arguments
end

#queryObject (readonly)

Returns the value of attribute query.



36
37
38
# File 'lib/graphql/root_call.rb', line 36

def query
  @query
end

Class Method Details

.abstract!Object

This call won’t be visible in ‘schema()`



103
104
105
# File 'lib/graphql/root_call.rb', line 103

def abstract!
  GraphQL::SCHEMA.remove_call(self)
end

.argumentGraphQL::RootCallArgumentDefiner

Use this object to declare arguments. They must be declared in order

Examples:

argument.string("post_title")
argument.object("comment_data") # allows a JSON object

Returns:



137
138
139
# File 'lib/graphql/root_call.rb', line 137

def argument
  @argument ||= GraphQL::RootCallArgumentDefiner.new(self)
end

.argumentsObject



145
146
147
148
149
150
# File 'lib/graphql/root_call.rb', line 145

def arguments
  own = own_arguments || []
  own + superclass.arguments
rescue NoMethodError
  own
end

.indentifier(ident_name) ⇒ Object

Declare an alternative name used in a query string

Parameters:

  • ident_name (String)


88
89
90
91
# File 'lib/graphql/root_call.rb', line 88

def indentifier(ident_name)
  @identifier = ident_name
  GraphQL::SCHEMA.add_call(self)
end

.inherited(child_class) ⇒ Object



98
99
100
# File 'lib/graphql/root_call.rb', line 98

def inherited(child_class)
  GraphQL::SCHEMA.add_call(child_class)
end

.own_argumentsObject



141
142
143
# File 'lib/graphql/root_call.rb', line 141

def own_arguments
  @argument && @argument.arguments
end

.return_declarationsObject



128
129
130
# File 'lib/graphql/root_call.rb', line 128

def return_declarations
  @return_declarations ||= {}
end

.returns(*return_declaration_names) ⇒ Object

Name of returned values from this call

Parameters:

  • return_declarations (Symbol)


109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/graphql/root_call.rb', line 109

def returns(*return_declaration_names)
  if return_declaration_names.last.is_a?(Hash)
    return_declarations_hash = return_declaration_names.pop
  else
    return_declarations_hash = {}
  end

  raise "Return keys must be symbols" if  (return_declarations.keys + return_declaration_names).any? { |k| !k.is_a?(Symbol) }

  return_declaration_names.each do |return_sym|
    return_type = return_sym.to_s
    return_declarations[return_sym] = return_type
  end

  return_declarations_hash.each do |return_sym, return_type|
    return_declarations[return_sym] = return_type
  end
end

.schema_nameObject

The name used by SCHEMA. Uses identifier or derives a name from the class name.



94
95
96
# File 'lib/graphql/root_call.rb', line 94

def schema_name
  @identifier || name.split("::").last.sub(/Call$/, '').underscore
end

Instance Method Details

#as_resultObject

Executes the call, validates the return values against declared returns, then returns the return values.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/graphql/root_call.rb', line 68

def as_result
  return_declarations = self.class.return_declarations
  raise "#{self.class.name} must declare returns" unless return_declarations.present?
  return_values = execute!(*arguments)

  if return_values.is_a?(Hash)
    unexpected_returns = return_values.keys - return_declarations.keys
    missing_returns = return_declarations.keys - return_values.keys
    if unexpected_returns.any?
      raise "#{self.class.name} returned #{unexpected_returns}, but didn't declare them."
    elsif missing_returns.any?
      raise "#{self.class.name} declared #{missing_returns}, but didn't return them."
    end
  end
  return_values
end

#contextObject

The object passed to Query#initialize as ‘context`



63
64
65
# File 'lib/graphql/root_call.rb', line 63

def context
  query.context
end

#execute!(*args) ⇒ Object

This method is invoked with the arguments provided to the query. It should do work and return values matching the returns declarations

Parameters:

  • args (Array)

    (splat) all args provided in query string (as strings)

Raises:

  • (NotImplementedError)


58
59
60
# File 'lib/graphql/root_call.rb', line 58

def execute!(*args)
  raise NotImplementedError, "Do work in this method"
end