class GraphQL::Schema::Argument
Arguments describe the input accepted by a field or input object. Keep argument-specific behavior and examples here; the guide is only an entry point for the broader fields documentation.
Fields can take arguments as input. These can be used to determine the return value (eg, filtering search results) or to modify the application state (eg, updating the database in MutationType).
Arguments are defined with the argument helper. These arguments are passed as keyword arguments to the resolver method:
field :search_posts, [PostType], null: false do argument :category, String end def search_posts(category:) Post.where(category: category).limit(10) end
Nullability
To make an argument optional, set required: false, and set default values for the corresponding keyword arguments:
field :search_posts, [PostType], null: false do argument :category, String, required: false end def search_posts(category: nil) if category Post.where(category: category).limit(10) else Post.all.limit(10) end end
Be aware that if all arguments are optional and the query does not provide any arguments, then the resolver method will be called with no arguments. To prevent an ArgumentError in this case, you must either specify default values for all keyword arguments (as done in the prior example) or use the double splat operator argument in the method definition. For example:
def search_posts(**args) if args[:category] Post.where(category: args[:category]).limit(10) else Post.all.limit(10) end end
Default Values
Another approach is to use default_value: value to provide a default value for the argument if it is not supplied in the query.
field :search_posts, [PostType], null: false do argument :category, String, required: false, default_value: "Programming" end def search_posts(category:) Post.where(category: category).limit(10) end
Arguments with required: false do accept null as inputs from clients. This can be surprising in resolver code, for example, an argument with Integer, required: false can sometimes be nil. In this case, you can use replace_null_with_default: true to apply the given default_value: ... when clients provide null. For example:
# Even if clients send `query: null`, the resolver will receive `"*"` for this argument: argument :query, String, required: false, default_value: "*", replace_null_with_default: true
Finally, required: :nullable will require clients to pass the argument, although it will accept null as a valid input. For example:
# This argument _must_ be given -- send `null` if there's no other appropriate value: argument :email_address, String, required: :nullable
Deprecation
Experimental: Deprecated arguments can be marked by adding a deprecation_reason: keyword argument:
field :search_posts, [PostType], null: false do argument :name, String, required: false, deprecation_reason: "Use `query` instead." argument :query, String, required: false end
Aliasing
Use as: :alternate_name to use a different key from within your resolvers while exposing another key to clients.
field :post, PostType, null: false do argument :post_id, ID, as: :id end def post(id:) Post.find(id) end
Preprocessing
Provide a prepare function to modify or validate the value of an argument before the fieldβs resolver method is executed:
field :posts, [PostType], null: false do argument :start_date, String, prepare: ->(startDate, ctx) { # return the prepared argument. # raise a GraphQL::ExecutionError to halt the execution of the field and # add the exception's message to the `errors` key. } end def posts(start_date:) # use prepared start_date end
Automatic camelization
Arguments that are snake_cased will be camelized in the GraphQL schema. Using the example of:
field :posts, [PostType], null: false do argument :start_year, Int end
The corresponding GraphQL query will look like:
{
posts(startYear: 2018) {
id
}
}
To disable auto-camelization, pass camelize: false to the argument method.
field :posts, [PostType], null: false do argument :start_year, Int, camelize: false end
Furthermore, if your argument is already camelCased, then it will remain camelized in the GraphQL schema. However, the argument will be converted to snake_case when it is passed to the resolver method:
field :posts, [PostType], null: false do argument :startYear, Int end def posts(start_year:) # ... end
Valid Argument Types
Only certain types are valid for arguments:
-
GraphQL::Schema::Scalar, including built-in scalars (string, int, float, boolean, ID) -
GraphQL::Schema::InputObject, which allows key-value pairs as input -
GraphQL::Schema::Lists of a valid input type, configured using[...] -
GraphQL::Schema::NonNulls of a valid input type (arguments are non-null by default; userequired: falseto make optional arguments)
Attributes
Returns
-
Stringβ theGraphQLname for this argument, camelized unlesscamelize: falseis provided
Returns
-
Symbolβ This argumentβs name in Ruby keyword arguments
Returns
-
Class, Module, nilβ If this argument should load an application object, this is the type of object to load
Returns
-
Stringβ theGraphQLname for this argument, camelized unlesscamelize: falseis provided
Returns
-
GraphQL::Schema::Field, Classβ The field or input object this argument belongs to
Public Class Methods
# File lib/graphql/schema/argument.rb, line 259 def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, comment: nil, ast_node: nil, default_value: NOT_CONFIGURED, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block) arg_name ||= name @name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s) NameValidator.validate!(@name) @type_expr = type_expr || type @description = desc || description @comment = comment @null = required != true @default_value = default_value if replace_null_with_default if !default_value? raise ArgumentError, "`replace_null_with_default: true` requires a default value, please provide one with `default_value: ...`" end @replace_null_with_default = true end @owner = owner @as = as @loads = loads @keyword = as || (arg_name.is_a?(Symbol) ? arg_name : Schema::Member::BuildType.underscore(@name).to_sym) @prepare = prepare @ast_node = ast_node @from_resolver = from_resolver self.deprecation_reason = deprecation_reason if directives directives.each do |dir_class, dir_options| directive(dir_class, **dir_options) end end if validates && !validates.empty? self.validates(validates) end if required == :nullable self.owner.validates(required: { argument: @keyword }) end if definition_block # `self` will still be self, it will also be the first argument to the block: instance_exec(self, &definition_block) end end
Parameters
-
arg_name(Symbol) -
type_expr -
desc(String) -
type(Class, Array<Class>) β Input type; positional argument also accepted -
name(Symbol) β positional argument also accepted -
definition_block(Proc) β Called with the newly-createdArgument -
owner(Class) β Private, used by GraphQL-Ruby during schema definition -
required(Boolean, :nullable) β if true, this argument is non-null; if false, this argument is nullable. If:nullable, then the argument must be provided, though it may benull. -
description(String) -
loads(Class, Array<Class>) β AGraphQLtype to load for the given ID when one is present -
as(Symbol) β Override the keyword name when passed to a method -
prepare(Symbol) β A method to call to transform this argumentβs valuebefore sending it to field resolution -
camelize(Boolean) β if true, the name will be camelized when building the schema -
from_resolver(Boolean) β if true, aResolverclass defined this argument -
directives(Hash{Class => Hash}) -
deprecation_reason(String) -
validates(Hash, nil) β Options for building validators, if any should be applied -
replace_null_with_default(Boolean) β iftrue, incoming values ofnullwill be replaced with the configureddefault_value -
comment(String) β Private, used by GraphQL-Ruby when parsingGraphQLschema files -
ast_node(GraphQL::Language::Nodes::InputValueDefinition) β Private, used by GraphQL-Ruby when parsing schema files
Public Instance Methods
Source
# File lib/graphql/schema/argument.rb, line 363 def comment(text = nil) if text @comment = text else @comment end end
Returns
-
Stringβ Comment for this argument
# File lib/graphql/schema/argument.rb, line 318 def default_value(new_default_value = NOT_CONFIGURED) if new_default_value != NOT_CONFIGURED @default_value = new_default_value end @default_value end
Parameters
-
default_value(Object) β The value to use when the client doesnβt provide one
Returns
-
Objectβ the value used when the client doesnβt provide a value for this argument
Source
# File lib/graphql/schema/argument.rb, line 331 def default_value? @default_value != NOT_CONFIGURED end
Returns
-
Booleanβ True if this argument has a default value
# File lib/graphql/schema/argument.rb, line 377 def deprecation_reason(text = nil) if text self.deprecation_reason = text else super() end end
Returns
-
Stringβ Deprecation reason for this argument
# File lib/graphql/schema/argument.rb, line 385 def deprecation_reason=(new_reason) validate_deprecated_or_optional(null: @null, deprecation_reason: new_reason) super end
GraphQL::Schema::Member::HasDeprecationReason#deprecation_reason=
Source
# File lib/graphql/schema/argument.rb, line 347 def description(text = nil) if text @description = text else @description end end
Returns
-
Stringβ Documentation for this argument
Source
# File lib/graphql/schema/argument.rb, line 453 def freeze statically_coercible? super end
Source
# File lib/graphql/schema/argument.rb, line 229 def from_resolver? @from_resolver end
Returns
-
Booleanβ true if a resolver defined this argument
Source
# File lib/graphql/schema/argument.rb, line 304 def inspect "#<#{self.class} #{path}: #{type.to_type_signature}#{description ? " @description=#{description.inspect}" : ""}>" end
# File lib/graphql/schema/argument.rb, line 206 def prepare(new_prepare = NOT_CONFIGURED) if new_prepare != NOT_CONFIGURED @prepare = new_prepare end @prepare end
Parameters
-
new_prepare(Method, Proc)
Returns
-
Symbolβ A method or proc to call to transform this value before sending it to field resolution method
# File lib/graphql/schema/argument.rb, line 335 def replace_null_with_default? @replace_null_with_default end
Source
# File lib/graphql/schema/argument.rb, line 447 def statically_coercible? return @statically_coercible if defined?(@statically_coercible) requires_parent_object = @prepare.is_a?(String) || @prepare.is_a?(Symbol) || @own_validators @statically_coercible = !requires_parent_object end
Source
# File lib/graphql/schema/argument.rb, line 435 def type @type ||= begin parsed_type = begin Member::BuildType.parse_type(@type_expr, null: @null) rescue StandardError => err raise ArgumentError, "Couldn't build type for Argument #{@owner.name}.#{name}: #{err.class.name}: #{err.message}", err.backtrace end # Use the setter method to get validations self.type = parsed_type end end
Source
# File lib/graphql/schema/argument.rb, line 425 def type=(new_type) validate_input_type(new_type) # This isn't true for LateBoundTypes, but we can assume those will # be updated via this codepath later in schema setup. if new_type.respond_to?(:non_null?) validate_deprecated_or_optional(null: !new_type.non_null?, deprecation_reason: deprecation_reason) end @type = new_type end
Source
# File lib/graphql/schema/argument.rb, line 390 def visible?(context) true end