Class: GraphQL::Node

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

Overview

Node is the base class for your GraphQL nodes. It’s essentially a delegator that only delegates methods you whitelist with Node.field. To use it:

Examples:

class PostNode < GraphQL::Node
  exposes('Post')

  cursor(:id)

  field.number(:id)
  field.string(:title)
  field.string(:content)
  field.connection(:comments)
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target = nil, fields:, query:) ⇒ Node

Returns a new instance of Node.



30
31
32
33
34
# File 'lib/graphql/node.rb', line 30

def initialize(target=nil, fields:, query:)
  @target = target
  @query = query
  @syntax_fields = fields
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object

If the target responds to ‘method_name`, send it to target.



37
38
39
40
41
42
43
# File 'lib/graphql/node.rb', line 37

def method_missing(method_name, *args, &block)
  if target.respond_to?(method_name)
    target.public_send(method_name, *args, &block)
  else
    super
  end
end

Instance Attribute Details

#queryObject (readonly)

The query to which this ‘Node` belongs. Used for accessing its Query#context.



28
29
30
# File 'lib/graphql/node.rb', line 28

def query
  @query
end

#syntax_fieldsObject (readonly)

Fields parsed from the query string



26
27
28
# File 'lib/graphql/node.rb', line 26

def syntax_fields
  @syntax_fields
end

#targetObject (readonly)

The object wrapped by this ‘Node`



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

def target
  @target
end

Class Method Details

.all_fieldsObject

All accessible fields on this node (including those defined in parent classes)



128
129
130
131
132
# File 'lib/graphql/node.rb', line 128

def all_fields
  superclass.all_fields.merge(own_fields)
rescue NoMethodError
  own_fields
end

.cursor(field_name) ⇒ Object

Declares what field will be used as the cursor for this node.

Parameters:

  • field_name (String)

    name of the field to be used as the cursor



118
119
120
121
122
123
124
125
# File 'lib/graphql/node.rb', line 118

def cursor(field_name)
  define_method "cursor" do
    field_class = self.class.all_fields[field_name.to_s]
    field = field_class.new(query: query, owner: self, calls: [])
    cursor = GraphQL::Types::CursorField.new(field.as_result)
    cursor.as_result
  end
end

.default_schema_nameObject



112
113
114
# File 'lib/graphql/node.rb', line 112

def default_schema_name
  name.split("::").last.sub(/Node$/, '').underscore
end

.desc(describe) ⇒ Object

Provide a description for this node which will be accessible from SCHEMA

Parameters:

  • describe (String)


91
92
93
# File 'lib/graphql/node.rb', line 91

def desc(describe)
  @description = describe
end

.descriptionObject

The description of this node



96
97
98
# File 'lib/graphql/node.rb', line 96

def description
  @description || raise("#{name}.description isn't defined")
end

.exposes(ruby_class_name) ⇒ Object

Parameters:

  • class_name (String)

    name of the class this node will wrap.



79
80
81
82
# File 'lib/graphql/node.rb', line 79

def exposes(ruby_class_name)
  @ruby_class_name = ruby_class_name
  GraphQL::SCHEMA.add_type(self)
end

.fieldGraphQL::FieldDefiner

Returns definer.

Returns:



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

def field
  @field_definer ||= GraphQL::FieldDefiner.new(self)
end

.inherited(child_class) ⇒ Object

Registers this node in SCHEMA



71
72
73
74
75
76
# File 'lib/graphql/node.rb', line 71

def inherited(child_class)
  # use name to prevent autoloading Connection
  if child_class.ancestors.map(&:name).include?("GraphQL::Connection")
    GraphQL::SCHEMA.add_connection(child_class)
  end
end

.own_fieldsObject

Fields defined by this class, but not its parents



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

def own_fields
  @own_fields ||= {}
end

.remove_field(field_name) ⇒ Object

Un-define field with name ‘field_name`

Parameters:

  • field_name (String)


146
147
148
# File 'lib/graphql/node.rb', line 146

def remove_field(field_name)
  own_fields.delete(field_name.to_s)
end

.ruby_class_nameObject

The name of the class wrapped by this node



85
86
87
# File 'lib/graphql/node.rb', line 85

def ruby_class_name
  @ruby_class_name
end

.schema_nameObject

Returns the name of this node used by SCHEMA



108
109
110
# File 'lib/graphql/node.rb', line 108

def schema_name
  @type_name || default_schema_name
end

.type(type_name) ⇒ Object

Declares an alternative name to use in SCHEMA

Parameters:

  • type_name (String)


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

def type(type_name)
  @type_name = type_name.to_s
  GraphQL::SCHEMA.add_type(self)
end

Instance Method Details

#as_resultObject

Looks up #syntax_fields against this node and returns the results



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/graphql/node.rb', line 46

def as_result
  json = {}
  syntax_fields.each do |syntax_field|
    key_name = syntax_field.alias_name || syntax_field.identifier
    if key_name == 'node'
      clone_node = self.class.new(target, fields: syntax_field.fields, query: query)
      json[key_name] = clone_node.as_result
    elsif key_name == 'cursor'
      json[key_name] = cursor
    else
      field = get_field(syntax_field)
      json[key_name] = field.as_result
    end
  end
  json
end

#contextObject

The object passed to Query#initialize as ‘context`.



64
65
66
# File 'lib/graphql/node.rb', line 64

def context
  query.context
end