Module: ElasticGraph::GraphQL::Schema::Arguments
- Defined in:
- lib/elastic_graph/graphql/schema/arguments.rb
Overview
A utility module for working with GraphQL schema arguments.
Class Method Summary collapse
-
.to_schema_form(args_value, args_owner) ⇒ Object
A utility method to convert the given ‘args_hash` to its schema form.
Class Method Details
.to_schema_form(args_value, args_owner) ⇒ Object
A utility method to convert the given ‘args_hash` to its schema form. The schema form is the casing of the arguments according to the GraphQL schema definition. For example, consider a case like:
type Query
(orderBy: [WidgetSort!]): [Widget!]!
The GraphQL gem converts all arguments to ruby keyword args style (symbolized, snake_case keys) before passing the args to us, but the ‘orderBy` argument in the schema definition uses camelCase. ElasticGraph was designed to flexibly support whatever casing the schema developer chooses to use but the GraphQL gem’s conversion to keyword args style gets in the way. ElasticGraph needs to receive the arguments in the casing form defined in the schema so that, for example, when it creates a datastore query, it correctly filters on fields according to the casing of the fields in the index.
This utility method converts an args hash back to its schema form (string keys, with the casing from the schema) by using the arg definitions themselves to get the arg names from the GraphQL schema.
Example:
to_schema_form({ order_by: ["size"] }, )
# => { "orderBy" => ["size"] }
The implementation here was taken from a code snippet provided by the maintainer of the GraphQL gem: github.com/rmosolgo/graphql-ruby/issues/2869
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/elastic_graph/graphql/schema/arguments.rb', line 42 def self.to_schema_form(args_value, args_owner) # For custom scalar types (such as `_Any` for apollo federation), `args_owner` won't # response to `arguments`. return args_value unless args_owner.respond_to?(:arguments) __skip__ = case args_value when Hash, ::GraphQL::Schema::InputObject arg_defns = args_owner.arguments.values {}.tap do |accumulator| args_value.each do |key, value| # Note: we could build `arg_defns` into a hash keyed by `keyword` # outside of this loop, to give us an O(1) lookup here. However, # usually there are a small number of args (e.g 1 or 2, maybe up # to 6 in extreme cases) so it's probably likely to be ultimately # slower to build the hash, particularly when you account for the # extra memory allocation and GC for the hash. arg_defn = arg_defns.find do |a| a.keyword == key end || raise(SchemaError, "Cannot find an argument definition for #{key.inspect} on `#{args_owner.name}`") next_owner = arg_defn.type.unwrap accumulator[arg_defn.name] = to_schema_form(value, next_owner) end end when Array args_value.map { |arg_value| to_schema_form(arg_value, args_owner) } else # :nocov: -- not sure how to cover this but we want this default branch. args_value # :nocov: end end |