Class: GraphQL::Rails::Operations::MutationDefinition

Inherits:
QueryDefinition show all
Defined in:
lib/graphql/rails/operations.rb

Overview

DSL for mutation definition.

Instance Method Summary collapse

Methods inherited from QueryDefinition

#description, #name, #uses

Methods inherited from DSL

#run

Constructor Details

#initialize(klass) ⇒ MutationDefinition

Returns a new instance of MutationDefinition.



148
149
150
151
152
# File 'lib/graphql/rails/operations.rb', line 148

def initialize(klass)
  super
  @input = ::GraphQL::InputObjectType.new
  @output = ::GraphQL::ObjectType.new
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class GraphQL::Rails::DSL

Instance Method Details

#argument(name, type, required = false) ⇒ Object



164
165
166
167
168
169
170
# File 'lib/graphql/rails/operations.rb', line 164

def argument(name, type, required = false)
  argument = ::GraphQL::Argument.define do
    name Types.to_field_name(name)
    type Types.resolve(type, required == :required)
  end
  @input.arguments[argument.name] = argument
end

#fieldObject



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/graphql/rails/operations.rb', line 172

def field
  # Build input object according to mutation specification.
  input = @input
  input.name = "#{@name.to_s.camelize(:upper)}Input"
  input.description = "Generated input type for #{@field.name}"
  input.arguments['clientMutationId'] = ::GraphQL::Argument.define do
    name 'clientMutationId'
    type Types.resolve(::String)
    description 'Unique identifier for client performing mutation'
  end

  # Build compound output object according to mutation specification.
  output = @output
  output.name = "#{@name.to_s.camelize(:upper)}Output"
  output.description = "Generated output type for #{@field.name}"
  output.fields['clientMutationId'] = ::GraphQL::Field.define do
    name 'clientMutationId'
    type Types.resolve(::String)
    description 'Unique identifier for client performing mutation'
  end

  @field.type = output
  @field.arguments['input'] = ::GraphQL::Argument.define do
    name 'input'
    type Types.resolve(input, true)
  end
  @field
end

#resolve(&block) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/graphql/rails/operations.rb', line 201

def resolve(&block)
  @field.resolve = -> (obj, args, ctx) do
    # Instantiate the Operations class with state on this query.
    instance = @klass.new({
      op: :mutation, name: @name, type: @type,
      obj: obj, args: Fields.new(args[:input]), ctx: ctx, context: ctx
    })

    begin
      # Run callbacks for this Operations class.
      instance.run_callbacks(:perform_operation) do
        # Call out to the app-defined resolver.
        result = instance.instance_eval(&block)

        # Transform the result keys to the expected convention.
        unless result.is_a?(::Hash)
          raise 'Mutation must resolve to a Hash result'
        end

        result = result.inject({
          'clientMutationId' => args['clientMutationId']
        }) do |hash, (key, value)|
          hash[Types.to_field_name(key)] = value
          hash
        end
        ::OpenStruct.new(result)
      end
    rescue => e
      # Surface messages from standard errors in GraphQL response.
      ::GraphQL::ExecutionError.new(e.message)
    rescue ::Exception => e
      # Log and genericize other runtime errors.
      Rails.logger.error "Unexpected exception during mutation: #{@name}"
      Rails.logger.exception e
      ::GraphQL::ExecutionError.new('Internal error')
    end
  end
end

#type(hash) ⇒ Object



154
155
156
157
158
159
160
161
162
# File 'lib/graphql/rails/operations.rb', line 154

def type(hash)
  hash.each do |name, type|
    field = ::GraphQL::Field.define do
      name Types.to_field_name(name)
      type Types.resolve(type)
    end
    @output.fields[field.name] = field
  end
end