Class: RuboCop::Cop::GraphQL::DefaultForOptionalArgument

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/graphql/default_for_optional_argument.rb

Overview

Optional arguments should have a default value in the resolver signature.

When the client omits an argument declared required: false, graphql-ruby leaves it out of the keyword arguments entirely, so a required keyword raises ArgumentError: missing keyword. Giving the keyword a default value is what makes the argument actually optional at runtime.

Arguments declared with a default_value: are always passed, so they are not reported. Neither is required: :nullable, which still demands the argument be present.

Both class-level arguments (checked against #resolve and #authorized?) and arguments defined inside a field block (checked against that field's resolver method) are covered.

Examples:

# bad

class SomeResolver < Resolvers::Base
  argument :name, String, required: false

  def resolve(name:); end
end

# good

class SomeResolver < Resolvers::Base
  argument :name, String, required: false

  def resolve(name: nil); end
end

# good - a default value means the keyword is always passed

class SomeResolver < Resolvers::Base
  argument :name, String, required: false, default_value: "anonymous"

  def resolve(name:); end
end

# bad

class UserType < BaseObject
  field :posts, [PostType], null: false do
    argument :limit, Integer, required: false
  end

  def posts(limit:); end
end

# good

class UserType < BaseObject
  field :posts, [PostType], null: false do
    argument :limit, Integer, required: false
  end

  def posts(limit: 10); end
end

Constant Summary collapse

MSG =
"Optional argument `%<keyword>s` has no default value in `%<method>s`, so " \
"omitting it raises ArgumentError."
RESOLVER_METHODS =
%i[resolve authorized?].freeze

Instance Method Summary collapse

Instance Method Details

#on_class(node) ⇒ Object



71
72
73
74
75
76
77
78
79
80
# File 'lib/rubocop/cop/graphql/default_for_optional_argument.rb', line 71

def on_class(node)
  body = node.body
  return unless body

  defs = definitions_in(node)
  return if defs.empty?

  check_class_arguments(node, defs)
  check_field_arguments(node, defs)
end