Class: ElasticGraph::GraphQL::Resolvers::GraphQLAdapter
- Inherits:
-
Object
- Object
- ElasticGraph::GraphQL::Resolvers::GraphQLAdapter
- Defined in:
- lib/elastic_graph/graphql/resolvers/graphql_adapter.rb
Overview
Adapts the GraphQL gem’s resolver interface to the interface implemented by our resolvers. Responsible for routing a resolution request to the appropriate resolver.
Instance Method Summary collapse
-
#call(parent_type, field, object, args, context) ⇒ Object
To be a valid resolver, we must implement ‘call`, accepting the 5 arguments listed here.
- #coerce_input(type, value, ctx) ⇒ Object
- #coerce_result(type, value, ctx) ⇒ Object
-
#initialize(schema:, datastore_query_builder:, datastore_query_adapters:, runtime_metadata:, resolvers:) ⇒ GraphQLAdapter
constructor
A new instance of GraphQLAdapter.
-
#resolve_type(supertype, object, context) ⇒ Object
In order to support unions and interfaces, we must implement ‘resolve_type`.
Constructor Details
#initialize(schema:, datastore_query_builder:, datastore_query_adapters:, runtime_metadata:, resolvers:) ⇒ GraphQLAdapter
Returns a new instance of GraphQLAdapter.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/elastic_graph/graphql/resolvers/graphql_adapter.rb', line 18 def initialize(schema:, datastore_query_builder:, datastore_query_adapters:, runtime_metadata:, resolvers:) @schema = schema @query_adapter = QueryAdapter.new( datastore_query_builder: datastore_query_builder, datastore_query_adapters: datastore_query_adapters ) @resolvers = resolvers scalar_types_by_name = .scalar_types_by_name @coercion_adapters_by_scalar_type_name = ::Hash.new do |hash, name| scalar_types_by_name.fetch(name).load_coercion_adapter.extension_class end end |
Instance Method Details
#call(parent_type, field, object, args, context) ⇒ Object
To be a valid resolver, we must implement ‘call`, accepting the 5 arguments listed here.
See graphql-ruby.org/api-doc/1.9.6/GraphQL/Schema.html#from_definition-class_method (specifically, the ‘default_resolve` argument) for the API documentation.
37 38 39 40 41 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 75 76 |
# File 'lib/elastic_graph/graphql/resolvers/graphql_adapter.rb', line 37 def call(parent_type, field, object, args, context) schema_field = @schema.field_named(parent_type.graphql_name, field.name) # Extract the `:lookahead` extra that we have configured all fields to provide. # See https://graphql-ruby.org/api-doc/1.10.8/GraphQL/Execution/Lookahead.html for more info. # It is not a "real" arg in the schema and breaks `args_to_schema_form` when we call that # so we need to peel it off here. lookahead = args[:lookahead] # Convert args to the form they were defined in the schema, undoing the normalization # the GraphQL gem does to convert them to Ruby keyword args form. args = schema_field.args_to_schema_form(args.except(:lookahead)) resolver = resolver_for(schema_field, object) do raise <<~ERROR No resolver yet implemented for this case. parent_type: #{schema_field.parent_type} field: #{schema_field} obj: #{object.inspect} args: #{args.inspect} ctx: #{context.inspect} ERROR end result = resolver.resolve(field: schema_field, object: object, args: args, context: context, lookahead: lookahead) do @query_adapter.build_query_from(field: schema_field, args: args, lookahead: lookahead, context: context) end # Give the field a chance to coerce the result before returning it. Initially, this is only used to deal with # enum value overrides (e.g. so that if `DayOfWeek.MONDAY` has been overridden to `DayOfWeek.MON`, we can coerce # a `MONDAY` value being returned by a painless script to `MON`), but this is designed to be general purpose # and we may use it for other coercions in the future. # # Note that coercion of scalar values is handled by the `coerce_result` callback below. schema_field.coerce_result(result) end |
#coerce_input(type, value, ctx) ⇒ Object
92 93 94 |
# File 'lib/elastic_graph/graphql/resolvers/graphql_adapter.rb', line 92 def coerce_input(type, value, ctx) scalar_coercion_adapter_for(type).coerce_input(value, ctx) end |
#coerce_result(type, value, ctx) ⇒ Object
96 97 98 |
# File 'lib/elastic_graph/graphql/resolvers/graphql_adapter.rb', line 96 def coerce_result(type, value, ctx) scalar_coercion_adapter_for(type).coerce_result(value, ctx) end |
#resolve_type(supertype, object, context) ⇒ Object
In order to support unions and interfaces, we must implement ‘resolve_type`.
79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/elastic_graph/graphql/resolvers/graphql_adapter.rb', line 79 def resolve_type(supertype, object, context) # If `__typename` is available, use that to resolve. It should be available on any embedded abstract types... # (See `Inventor` in `config/schema.graphql` for an example of this kind of type union.) if (typename = object["__typename"]) @schema.graphql_schema.possible_types(supertype).find { |t| t.graphql_name == typename } else # ...otherwise infer the type based on what index the object came from. This is the case # with unions/interfaces of individually indexed types. # (See `Part` in `config/schema/widgets.rb` for an example of this kind of type union.) @schema.document_type_stored_in(object.index_definition_name).graphql_type end end |