class GraphQL::ScalarType

# GraphQL::ScalarType

Scalars are plain values. They are leaf nodes in a GraphQL query tree.

## Built-in Scalars

`GraphQL` comes with standard built-in scalars:

|Constant | `.define` helper| |——-|——–| |`GraphQL::STRING_TYPE` | `types.String`| |`GraphQL::INT_TYPE` | `types.Int`| |`GraphQL::FLOAT_TYPE` | `types.Float`| |`GraphQL::ID_TYPE` | `types.ID`| |`GraphQL::BOOLEAN_TYPE` | `types.Boolean`|

(`types` is an instance of `GraphQL::Definition::TypeDefiner`; `.String`, `.Float`, etc are methods which return built-in scalars.)

## Custom Scalars

You can define custom scalars for your GraphQL server. It requires some special functions:

@example defining a type for Time

TimeType = GraphQL::ScalarType.define do
  name "Time"
  description "Time since epoch in seconds"

  coerce_input ->(value, ctx) { Time.at(Float(value)) }
  coerce_result ->(value, ctx) { value.to_f }
end

You can customize the error message for invalid input values by raising a `GraphQL::CoercionError` within `coerce_input`:

@example raising a custom error message

TimeType = GraphQL::ScalarType.define do
  name "Time"
  description "Time since epoch in seconds"

  coerce_input ->(value, ctx) do
    begin
      Time.at(Float(value))
    rescue ArgumentError
      raise GraphQL::CoercionError, "cannot coerce `#{value.inspect}` to Float"
    end
  end

  coerce_result ->(value, ctx) { value.to_f }
end

This will result in the message of the `GraphQL::CoercionError` being used in the error response:

@example custom error response

{"message"=>"cannot coerce `"2"` to Float", "locations"=>[{"line"=>3, "column"=>9}], "fields"=>["arg"]}

Public Class Methods

new() click to toggle source
Calls superclass method GraphQL::BaseType::new
# File lib/graphql/scalar_type.rb, line 71
def initialize
  super
  self.coerce = NoOpCoerce
end

Public Instance Methods

coerce=(proc) click to toggle source
# File lib/graphql/scalar_type.rb, line 76
def coerce=(proc)
  self.coerce_input = proc
  self.coerce_result = proc
end
coerce_input=(coerce_input_fn) click to toggle source
# File lib/graphql/scalar_type.rb, line 81
def coerce_input=(coerce_input_fn)
  if !coerce_input_fn.nil?
    @coerce_input_proc = ensure_two_arg(coerce_input_fn, :coerce_input)
  end
end
coerce_result(value, ctx = nil) click to toggle source
# File lib/graphql/scalar_type.rb, line 87
def coerce_result(value, ctx = nil)
  if ctx.nil?
    warn_deprecated_coerce("coerce_isolated_result")
    ctx = GraphQL::Query::NullContext
  end
  @coerce_result_proc.call(value, ctx)
end
coerce_result=(coerce_result_fn) click to toggle source
# File lib/graphql/scalar_type.rb, line 95
def coerce_result=(coerce_result_fn)
  if !coerce_result_fn.nil?
    @coerce_result_proc = ensure_two_arg(coerce_result_fn, :coerce_result)
  end
end
kind() click to toggle source
# File lib/graphql/scalar_type.rb, line 101
def kind
  GraphQL::TypeKinds::SCALAR
end

Private Instance Methods

coerce_non_null_input(value, ctx) click to toggle source
# File lib/graphql/scalar_type.rb, line 111
def coerce_non_null_input(value, ctx)
  @coerce_input_proc.call(raw_coercion_input(value), ctx)
end
ensure_two_arg(callable, method_name) click to toggle source
# File lib/graphql/scalar_type.rb, line 107
def ensure_two_arg(callable, method_name)
  GraphQL::BackwardsCompatibility.wrap_arity(callable, from: 1, to: 2, name: "#{name}.#{method_name}(val, ctx)")
end
raw_coercion_input(value) click to toggle source
# File lib/graphql/scalar_type.rb, line 115
def raw_coercion_input(value)
  if value.is_a?(GraphQL::Language::Nodes::InputObject)
    value.to_h
  elsif value.is_a?(Array)
    value.map { |element| raw_coercion_input(element) }
  elsif value.is_a?(GraphQL::Language::Nodes::Enum)
    value.name
  else
    value
  end
end
validate_non_null_input(value, ctx) click to toggle source
# File lib/graphql/scalar_type.rb, line 127
def validate_non_null_input(value, ctx)
  result = Query::InputValidationResult.new
  if coerce_non_null_input(value, ctx).nil?
    result.add_problem("Could not coerce value #{GraphQL::Language.serialize(value)} to #{name}")
  end
  result
end