diff --git a/README.md b/README.md index 6151a6a3..6e315745 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ While `Client` is sufficient for most usecases, the library offers several discr ![Merging types](./docs/images/merging.png) -To facilitate this merging of types, stitching must know how to cross-reference and fetch each variant of a type from its source location using [resolver queries](#merged-type-resolver-queries). For those in an Apollo ecosystem, there's also _limited_ support for merging types though a [federation `_entities` protocol](./docs/federation_entities.md). +To facilitate this merging of types, stitching must know how to cross-reference and fetch each variant of a type from its source location using [type resolver queries](#merged-type-resolver-queries). For those in an Apollo ecosystem, there's also _limited_ support for merging types though a [federation `_entities` protocol](./docs/federation_entities.md). ### Merged type resolver queries @@ -249,7 +249,7 @@ type Query { } ``` -See [resolver arguments](./docs/resolver.md#arguments) for full documentation on shaping input. +See [resolver arguments](./docs/type_resolver.md#arguments) for full documentation on shaping input. #### Composite type keys diff --git a/docs/resolver.md b/docs/type_resolver.md similarity index 85% rename from docs/resolver.md rename to docs/type_resolver.md index a9625966..a5804f33 100644 --- a/docs/resolver.md +++ b/docs/type_resolver.md @@ -1,10 +1,10 @@ -## GraphQL::Stitching::Resolver +## GraphQL::Stitching::TypeResolver -A `Resolver` contains all information about a root query used by stitching to fetch location-specific variants of a merged type. Specifically, resolvers manage parsed keys and argument structures. +A `TypeResolver` contains all information about a root query used by stitching to fetch location-specific variants of a merged type. Specifically, resolvers manage parsed keys and argument structures. ### Arguments -Resolvers configure arguments through a template string of [GraphQL argument literal syntax](https://spec.graphql.org/October2021/#sec-Language.Arguments). This allows sending multiple arguments that intermix stitching keys with complex object shapes and other static values. +Type resolvers configure arguments through a template string of [GraphQL argument literal syntax](https://spec.graphql.org/October2021/#sec-Language.Arguments). This allows sending multiple arguments that intermix stitching keys with complex object shapes and other static values. #### Key insertions diff --git a/lib/graphql/stitching.rb b/lib/graphql/stitching.rb index 95c2d43c..941514bd 100644 --- a/lib/graphql/stitching.rb +++ b/lib/graphql/stitching.rb @@ -50,6 +50,6 @@ def stitching_directive_names require_relative "stitching/plan" require_relative "stitching/planner" require_relative "stitching/request" -require_relative "stitching/resolver" +require_relative "stitching/type_resolver" require_relative "stitching/util" require_relative "stitching/version" diff --git a/lib/graphql/stitching/composer.rb b/lib/graphql/stitching/composer.rb index 9057a316..e29e1eed 100644 --- a/lib/graphql/stitching/composer.rb +++ b/lib/graphql/stitching/composer.rb @@ -2,8 +2,8 @@ require_relative "composer/base_validator" require_relative "composer/validate_interfaces" -require_relative "composer/validate_resolvers" -require_relative "composer/resolver_config" +require_relative "composer/validate_type_resolvers" +require_relative "composer/type_resolver_config" module GraphQL module Stitching @@ -31,7 +31,7 @@ class T < GraphQL::Schema::Object # @api private COMPOSITION_VALIDATORS = [ ValidateInterfaces, - ValidateResolvers, + ValidateTypeResolvers, ].freeze # @return [String] name of the Query type in the composed schema. @@ -199,8 +199,8 @@ def prepare_locations_input(locations_input) raise CompositionError, "The schema for `#{location}` location must be a GraphQL::Schema class." end - @resolver_configs.merge!(ResolverConfig.extract_directive_assignments(schema, location, input[:stitch])) - @resolver_configs.merge!(ResolverConfig.extract_federation_entities(schema, location)) + @resolver_configs.merge!(TypeResolverConfig.extract_directive_assignments(schema, location, input[:stitch])) + @resolver_configs.merge!(TypeResolverConfig.extract_federation_entities(schema, location)) schemas[location.to_s] = schema executables[location.to_s] = input[:executable] || schema @@ -546,13 +546,13 @@ def extract_resolvers(type_name, types_by_location) subgraph_field.directives.each do |directive| next unless directive.graphql_name == GraphQL::Stitching.stitch_directive - resolver_configs << ResolverConfig.from_kwargs(directive.arguments.keyword_arguments) + resolver_configs << TypeResolverConfig.from_kwargs(directive.arguments.keyword_arguments) end resolver_configs.each do |config| resolver_type_name = if config.type_name if !resolver_type.kind.abstract? - raise CompositionError, "Resolver config may only specify a type name for abstract resolvers." + raise CompositionError, "Type resolver config may only specify a type name for abstract resolvers." elsif !resolver_type.possible_types.find { _1.graphql_name == config.type_name } raise CompositionError, "Type `#{config.type_name}` is not a possible return type for query `#{field_name}`." end @@ -561,7 +561,7 @@ def extract_resolvers(type_name, types_by_location) resolver_type.graphql_name end - key = Resolver.parse_key_with_types( + key = TypeResolver.parse_key_with_types( config.key, @subgraph_types_by_name_and_location[resolver_type_name], ) @@ -581,11 +581,11 @@ def extract_resolvers(type_name, types_by_location) "#{argument.graphql_name}: $.#{key.primitive_name}" end - arguments = Resolver.parse_arguments_with_field(arguments_format, subgraph_field) + arguments = TypeResolver.parse_arguments_with_field(arguments_format, subgraph_field) arguments.each { _1.verify_key(key) } @resolver_map[resolver_type_name] ||= [] - @resolver_map[resolver_type_name] << Resolver.new( + @resolver_map[resolver_type_name] << TypeResolver.new( location: location, type_name: resolver_type_name, field: subgraph_field.name, diff --git a/lib/graphql/stitching/composer/resolver_config.rb b/lib/graphql/stitching/composer/type_resolver_config.rb similarity index 95% rename from lib/graphql/stitching/composer/resolver_config.rb rename to lib/graphql/stitching/composer/type_resolver_config.rb index 1ba17d9b..67b0cf21 100644 --- a/lib/graphql/stitching/composer/resolver_config.rb +++ b/lib/graphql/stitching/composer/type_resolver_config.rb @@ -2,7 +2,7 @@ module GraphQL::Stitching class Composer - class ResolverConfig + class TypeResolverConfig ENTITY_TYPENAME = "_Entity" ENTITIES_QUERY = "_entities" @@ -30,7 +30,7 @@ def extract_federation_entities(schema, location) entity_type.directives.each do |directive| next unless directive.graphql_name == "key" - key = Resolver.parse_key(directive.arguments.keyword_arguments.fetch(:fields)) + key = TypeResolver.parse_key(directive.arguments.keyword_arguments.fetch(:fields)) key_fields = key.map { "#{_1.name}: $.#{_1.name}" } field_path = "#{location}._entities" diff --git a/lib/graphql/stitching/composer/validate_resolvers.rb b/lib/graphql/stitching/composer/validate_type_resolvers.rb similarity index 99% rename from lib/graphql/stitching/composer/validate_resolvers.rb rename to lib/graphql/stitching/composer/validate_type_resolvers.rb index c91aadfd..49bfd4bc 100644 --- a/lib/graphql/stitching/composer/validate_resolvers.rb +++ b/lib/graphql/stitching/composer/validate_type_resolvers.rb @@ -2,7 +2,7 @@ module GraphQL::Stitching class Composer - class ValidateResolvers < BaseValidator + class ValidateTypeResolvers < BaseValidator def perform(supergraph, composer) root_types = [ diff --git a/lib/graphql/stitching/executor.rb b/lib/graphql/stitching/executor.rb index c53bb938..0e8d726b 100644 --- a/lib/graphql/stitching/executor.rb +++ b/lib/graphql/stitching/executor.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true require "json" -require_relative "executor/resolver_source" require_relative "executor/root_source" +require_relative "executor/type_resolver_source" require_relative "executor/shaper" module GraphQL @@ -66,7 +66,7 @@ def exec!(next_steps = [@after]) .select { next_steps.include?(_1.after) } .group_by { [_1.location, _1.resolver.nil?] } .map do |(location, root_source), ops| - source_class = root_source ? RootSource : ResolverSource + source_class = root_source ? RootSource : TypeResolverSource @dataloader.with(source_class, self, location).request_all(ops) end diff --git a/lib/graphql/stitching/executor/shaper.rb b/lib/graphql/stitching/executor/shaper.rb index c07525fb..4e04b933 100644 --- a/lib/graphql/stitching/executor/shaper.rb +++ b/lib/graphql/stitching/executor/shaper.rb @@ -23,8 +23,8 @@ def perform!(raw) def resolve_object_scope(raw_object, parent_type, selections, typename = nil) return nil if raw_object.nil? - typename ||= raw_object[Resolver::TYPENAME_EXPORT_NODE.alias] - raw_object.reject! { |key, _v| Resolver.export_key?(key) } + typename ||= raw_object[TypeResolver::TYPENAME_EXPORT_NODE.alias] + raw_object.reject! { |key, _v| TypeResolver.export_key?(key) } selections.each do |node| case node diff --git a/lib/graphql/stitching/executor/resolver_source.rb b/lib/graphql/stitching/executor/type_resolver_source.rb similarity index 98% rename from lib/graphql/stitching/executor/resolver_source.rb rename to lib/graphql/stitching/executor/type_resolver_source.rb index ebddb914..4d4a8121 100644 --- a/lib/graphql/stitching/executor/resolver_source.rb +++ b/lib/graphql/stitching/executor/type_resolver_source.rb @@ -2,7 +2,7 @@ module GraphQL::Stitching class Executor - class ResolverSource < GraphQL::Dataloader::Source + class TypeResolverSource < GraphQL::Dataloader::Source def initialize(executor, location) @executor = executor @location = location @@ -17,7 +17,7 @@ def fetch(ops) if op.if_type # operations planned around unused fragment conditions should not trigger requests - origin_set.select! { _1[Resolver::TYPENAME_EXPORT_NODE.alias] == op.if_type } + origin_set.select! { _1[TypeResolver::TYPENAME_EXPORT_NODE.alias] == op.if_type } end memo[op] = origin_set if origin_set.any? diff --git a/lib/graphql/stitching/planner.rb b/lib/graphql/stitching/planner.rb index c3ee9313..68338d47 100644 --- a/lib/graphql/stitching/planner.rb +++ b/lib/graphql/stitching/planner.rb @@ -215,8 +215,8 @@ def extract_locale_selections( input_selections.each do |node| case node when GraphQL::Language::Nodes::Field - if node.alias&.start_with?(Resolver::EXPORT_PREFIX) - raise StitchingError, %(Alias "#{node.alias}" is not allowed because "#{Resolver::EXPORT_PREFIX}" is a reserved prefix.) + if node.alias&.start_with?(TypeResolver::EXPORT_PREFIX) + raise StitchingError, %(Alias "#{node.alias}" is not allowed because "#{TypeResolver::EXPORT_PREFIX}" is a reserved prefix.) elsif node.name == TYPENAME locale_selections << node next @@ -277,8 +277,8 @@ def extract_locale_selections( # B.4) Add a `__typename` export to abstracts and types that implement # fragments so that resolved type information is available during execution. - if requires_typename && !locale_selections.include?(Resolver::TYPENAME_EXPORT_NODE) - locale_selections << Resolver::TYPENAME_EXPORT_NODE + if requires_typename && !locale_selections.include?(TypeResolver::TYPENAME_EXPORT_NODE) + locale_selections << TypeResolver::TYPENAME_EXPORT_NODE end if remote_selections @@ -294,7 +294,7 @@ def extract_locale_selections( # E.1) Add the key of each resolver query into the prior location's selection set. parent_selections.push(*resolver.key.export_nodes) if resolver.key parent_selections.uniq! do |node| - export_node = node.is_a?(GraphQL::Language::Nodes::Field) && Resolver.export_key?(node.alias) + export_node = node.is_a?(GraphQL::Language::Nodes::Field) && TypeResolver.export_key?(node.alias) export_node ? node.alias : node.object_id end diff --git a/lib/graphql/stitching/request/skip_include.rb b/lib/graphql/stitching/request/skip_include.rb index 94dfab73..935548b9 100644 --- a/lib/graphql/stitching/request/skip_include.rb +++ b/lib/graphql/stitching/request/skip_include.rb @@ -40,7 +40,7 @@ def render_node(parent_node, variables) end if filtered_selections.none? - filtered_selections << Resolver::TYPENAME_EXPORT_NODE + filtered_selections << TypeResolver::TYPENAME_EXPORT_NODE end if changed diff --git a/lib/graphql/stitching/supergraph.rb b/lib/graphql/stitching/supergraph.rb index d7ea30b8..9529435b 100644 --- a/lib/graphql/stitching/supergraph.rb +++ b/lib/graphql/stitching/supergraph.rb @@ -166,7 +166,7 @@ def route_type_to_locations(type_name, start_location, goal_locations) if key_count.zero? # nested root scopes have no resolver keys and just return a location goal_locations.each_with_object({}) do |goal_location, memo| - memo[goal_location] = [Resolver.new(location: goal_location)] + memo[goal_location] = [TypeResolver.new(location: goal_location)] end elsif key_count > 1 diff --git a/lib/graphql/stitching/supergraph/to_definition.rb b/lib/graphql/stitching/supergraph/to_definition.rb index bddde7f1..29d001ea 100644 --- a/lib/graphql/stitching/supergraph/to_definition.rb +++ b/lib/graphql/stitching/supergraph/to_definition.rb @@ -32,7 +32,7 @@ def from_definition(schema, executables:) end key_definitions = locations_by_key.each_with_object({}) do |(key, locations), memo| - memo[key] = Resolver.parse_key(key, locations) + memo[key] = TypeResolver.parse_key(key, locations) end # Collect/build resolver definitions for each type @@ -41,13 +41,13 @@ def from_definition(schema, executables:) kwargs = directive.arguments.keyword_arguments resolver_map[type_name] ||= [] - resolver_map[type_name] << Resolver.new( + resolver_map[type_name] << TypeResolver.new( location: kwargs[:location], type_name: kwargs.fetch(:type_name, type_name), field: kwargs[:field], list: kwargs[:list] || false, key: key_definitions[kwargs[:key]], - arguments: Resolver.parse_arguments_with_type_defs(kwargs[:arguments], kwargs[:argument_types]), + arguments: TypeResolver.parse_arguments_with_type_defs(kwargs[:arguments], kwargs[:argument_types]), ) end diff --git a/lib/graphql/stitching/resolver.rb b/lib/graphql/stitching/type_resolver.rb similarity index 93% rename from lib/graphql/stitching/resolver.rb rename to lib/graphql/stitching/type_resolver.rb index e5814063..3f2aaa04 100644 --- a/lib/graphql/stitching/resolver.rb +++ b/lib/graphql/stitching/type_resolver.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true -require_relative "resolver/arguments" -require_relative "resolver/keys" +require_relative "type_resolver/arguments" +require_relative "type_resolver/keys" module GraphQL module Stitching # Defines a type resolver query that provides direct access to an entity type. - class Resolver + class TypeResolver extend ArgumentsParser extend KeysParser diff --git a/lib/graphql/stitching/resolver/arguments.rb b/lib/graphql/stitching/type_resolver/arguments.rb similarity index 95% rename from lib/graphql/stitching/resolver/arguments.rb rename to lib/graphql/stitching/type_resolver/arguments.rb index 7673b12a..e2382dac 100644 --- a/lib/graphql/stitching/resolver/arguments.rb +++ b/lib/graphql/stitching/type_resolver/arguments.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module GraphQL::Stitching - class Resolver + class TypeResolver # Defines a single resolver argument structure # @api private class Argument @@ -129,9 +129,9 @@ def key? end def verify_key(arg, key) - key_field = value.reduce(Resolver::KeyField.new("", inner: key)) do |field, ns| + key_field = value.reduce(TypeResolver::KeyField.new("", inner: key)) do |field, ns| if ns == TYPENAME - Resolver::KeyField.new(TYPENAME) + TypeResolver::KeyField.new(TYPENAME) elsif field field.inner.find { _1.name == ns } end @@ -146,7 +146,7 @@ def verify_key(arg, key) def build(origin_obj) value.each_with_index.reduce(origin_obj) do |obj, (ns, idx)| - obj[idx.zero? ? Resolver.export_key(ns) : ns] + obj[idx.zero? ? TypeResolver.export_key(ns) : ns] end end @@ -174,7 +174,7 @@ module ArgumentsParser # Parses an argument template string into resolver arguments via schema casting. # @param template [String] the template string to parse. # @param field_def [GraphQL::Schema::FieldDefinition] a field definition providing arguments schema. - # @return [[GraphQL::Stitching::Resolver::Argument]] an array of resolver arguments. + # @return [[GraphQL::Stitching::TypeResolver::Argument]] an array of resolver arguments. def parse_arguments_with_field(template, field_def) ast = parse_arg_defs(template) args = build_argument_set(ast, field_def.arguments) @@ -196,7 +196,7 @@ def parse_arguments_with_field(template, field_def) # Parses an argument template string into resolver arguments via SDL casting. # @param template [String] the template string to parse. # @param type_defs [String] the type definition string declaring argument types. - # @return [[GraphQL::Stitching::Resolver::Argument]] an array of resolver arguments. + # @return [[GraphQL::Stitching::TypeResolver::Argument]] an array of resolver arguments. def parse_arguments_with_type_defs(template, type_defs) type_map = parse_type_defs(type_defs) parse_arg_defs(template).map { build_argument(_1, type_struct: type_map[_1.name]) } diff --git a/lib/graphql/stitching/resolver/keys.rb b/lib/graphql/stitching/type_resolver/keys.rb similarity index 99% rename from lib/graphql/stitching/resolver/keys.rb rename to lib/graphql/stitching/type_resolver/keys.rb index e3bf09db..41fdce14 100644 --- a/lib/graphql/stitching/resolver/keys.rb +++ b/lib/graphql/stitching/type_resolver/keys.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module GraphQL::Stitching - class Resolver + class TypeResolver EXPORT_PREFIX = "_export_" class FieldNode diff --git a/test/graphql/stitching/composer/configuration_test.rb b/test/graphql/stitching/composer/configuration_test.rb index ad87011f..ad954b49 100644 --- a/test/graphql/stitching/composer/configuration_test.rb +++ b/test/graphql/stitching/composer/configuration_test.rb @@ -44,21 +44,21 @@ def test_perform_with_static_resolver_config expected_resolvers = { "Product" => [ - GraphQL::Stitching::Resolver.new( + GraphQL::Stitching::TypeResolver.new( location: "alpha", type_name: "Product", list: false, field: "productA", - key: GraphQL::Stitching::Resolver.parse_key("id"), - arguments: GraphQL::Stitching::Resolver.parse_arguments_with_type_defs("id: $.id", "id: ID"), + key: GraphQL::Stitching::TypeResolver.parse_key("id"), + arguments: GraphQL::Stitching::TypeResolver.parse_arguments_with_type_defs("id: $.id", "id: ID"), ), - GraphQL::Stitching::Resolver.new( + GraphQL::Stitching::TypeResolver.new( location: "bravo", type_name: "Product", list: false, field: "productB", - key: GraphQL::Stitching::Resolver.parse_key("id"), - arguments: GraphQL::Stitching::Resolver.parse_arguments_with_type_defs("key: $.id", "key: ID"), + key: GraphQL::Stitching::TypeResolver.parse_key("id"), + arguments: GraphQL::Stitching::TypeResolver.parse_arguments_with_type_defs("key: $.id", "key: ID"), ), ] } @@ -75,7 +75,7 @@ def test_perform_federation_schema type Query { _entities(representations: [_Any!]!): [_Entity]! } | - configs = GraphQL::Stitching::Composer::ResolverConfig.extract_federation_entities( + configs = GraphQL::Stitching::Composer::TypeResolverConfig.extract_federation_entities( GraphQL::Schema.from_definition(schema), "alpha", ) diff --git a/test/graphql/stitching/composer/merge_resolvers_test.rb b/test/graphql/stitching/composer/merge_resolvers_test.rb index 5f5d789f..22b8f43f 100644 --- a/test/graphql/stitching/composer/merge_resolvers_test.rb +++ b/test/graphql/stitching/composer/merge_resolvers_test.rb @@ -10,21 +10,21 @@ def test_creates_resolver_map expected_resolvers_map = { "Test" => [ - GraphQL::Stitching::Resolver.new( + GraphQL::Stitching::TypeResolver.new( location: "a", type_name: "Test", list: false, field: "a", - key: GraphQL::Stitching::Resolver.parse_key("id"), - arguments: GraphQL::Stitching::Resolver.parse_arguments_with_type_defs("id: $.id", "id: ID"), + key: GraphQL::Stitching::TypeResolver.parse_key("id"), + arguments: GraphQL::Stitching::TypeResolver.parse_arguments_with_type_defs("id: $.id", "id: ID"), ), - GraphQL::Stitching::Resolver.new( + GraphQL::Stitching::TypeResolver.new( location: "b", type_name: "Test", list: true, field: "b", - key: GraphQL::Stitching::Resolver.parse_key("id"), - arguments: GraphQL::Stitching::Resolver.parse_arguments_with_type_defs("ids: $.id", "ids: [ID]"), + key: GraphQL::Stitching::TypeResolver.parse_key("id"), + arguments: GraphQL::Stitching::TypeResolver.parse_arguments_with_type_defs("ids: $.id", "ids: [ID]"), ), ], } @@ -256,8 +256,8 @@ def assert_resolver(supergraph, type_name, location:, key: nil, field: nil, arg: conditions << (b.location == location) conditions << (b.field == field) if field conditions << (b.arguments.first.name == arg) if arg - conditions << (b.arguments.first.value == GraphQL::Stitching::Resolver::KeyArgumentValue.new(key)) if key - conditions << (b.key == GraphQL::Stitching::Resolver.parse_key(key)) if key + conditions << (b.arguments.first.value == GraphQL::Stitching::TypeResolver::KeyArgumentValue.new(key)) if key + conditions << (b.key == GraphQL::Stitching::TypeResolver.parse_key(key)) if key conditions.all? end assert resolver, "No resolver found for #{[location, type_name, key, field, arg].join(".")}" diff --git a/test/graphql/stitching/executor/resolver_source_test.rb b/test/graphql/stitching/executor/resolver_source_test.rb index 8add8f9d..be6252e2 100644 --- a/test/graphql/stitching/executor/resolver_source_test.rb +++ b/test/graphql/stitching/executor/resolver_source_test.rb @@ -2,23 +2,23 @@ require "test_helper" -describe "GraphQL::Stitching::Executor, ResolverSource" do +describe "GraphQL::Stitching::Executor, TypeResolverSource" do def setup - @resolver1 = GraphQL::Stitching::Resolver.new( + @resolver1 = GraphQL::Stitching::TypeResolver.new( location: "products", type_name: "Storefront", list: true, field: "storefronts", - key: GraphQL::Stitching::Resolver.parse_key("id"), - arguments: GraphQL::Stitching::Resolver.parse_arguments_with_type_defs("ids: $.id", "ids: [ID]"), + key: GraphQL::Stitching::TypeResolver.parse_key("id"), + arguments: GraphQL::Stitching::TypeResolver.parse_arguments_with_type_defs("ids: $.id", "ids: [ID]"), ) - @resolver2 = GraphQL::Stitching::Resolver.new( + @resolver2 = GraphQL::Stitching::TypeResolver.new( location: "products", type_name: "Product", list: false, field: "product", - key: GraphQL::Stitching::Resolver.parse_key("upc"), - arguments: GraphQL::Stitching::Resolver.parse_arguments_with_type_defs("upc: $.upc", "upc: ID"), + key: GraphQL::Stitching::TypeResolver.parse_key("upc"), + arguments: GraphQL::Stitching::TypeResolver.parse_arguments_with_type_defs("upc: $.upc", "upc: ID"), ) @op1 = GraphQL::Stitching::Plan::Op.new( @@ -50,7 +50,7 @@ def setup }) request = GraphQL::Stitching::Request.new(supergraph, "{ test }") executor = GraphQL::Stitching::Executor.new(request) - @source = GraphQL::Stitching::Executor::ResolverSource.new(executor, "products") + @source = GraphQL::Stitching::Executor::TypeResolverSource.new(executor, "products") @origin_sets_by_operation = { @op1 => [{ "_export_id" => "7" }, { "_export_id" => "8" }], @op2 => [{ "_export_upc" => "abc" }, { "_export_upc" => "xyz" }], @@ -173,7 +173,7 @@ def with_mock_source mock = GraphQL::Stitching::Executor.new(mock) mock.instance_variable_set(:@data, data) - source = GraphQL::Stitching::Executor::ResolverSource.new(mock, "products") + source = GraphQL::Stitching::Executor::TypeResolverSource.new(mock, "products") origin_sets_by_operation = { @op1 => data["storefronts"], @op2 => data["storefronts"].map { _1["product"] }, diff --git a/test/graphql/stitching/plan_test.rb b/test/graphql/stitching/plan_test.rb index 2d2d6d66..8a8d6676 100644 --- a/test/graphql/stitching/plan_test.rb +++ b/test/graphql/stitching/plan_test.rb @@ -4,13 +4,13 @@ describe "GraphQL::Stitching::Plan" do def setup - @resolver = GraphQL::Stitching::Resolver.new( + @resolver = GraphQL::Stitching::TypeResolver.new( location: "products", type_name: "Storefront", list: true, field: "storefronts", - key: GraphQL::Stitching::Resolver.parse_key("id"), - arguments: GraphQL::Stitching::Resolver.parse_arguments_with_type_defs("ids: $.id", "ids: [ID]"), + key: GraphQL::Stitching::TypeResolver.parse_key("id"), + arguments: GraphQL::Stitching::TypeResolver.parse_arguments_with_type_defs("ids: $.id", "ids: [ID]"), ) @op = GraphQL::Stitching::Plan::Op.new( diff --git a/test/graphql/stitching/resolver/arguments_test.rb b/test/graphql/stitching/resolver/arguments_test.rb index 460c07be..7b7e8858 100644 --- a/test/graphql/stitching/resolver/arguments_test.rb +++ b/test/graphql/stitching/resolver/arguments_test.rb @@ -2,12 +2,12 @@ require "test_helper" -class GraphQL::Stitching::Resolver::ArgumentsTest < Minitest::Test - Argument = GraphQL::Stitching::Resolver::Argument - ObjectArgumentValue = GraphQL::Stitching::Resolver::ObjectArgumentValue - LiteralArgumentValue = GraphQL::Stitching::Resolver::LiteralArgumentValue - EnumArgumentValue = GraphQL::Stitching::Resolver::EnumArgumentValue - KeyArgumentValue = GraphQL::Stitching::Resolver::KeyArgumentValue +class GraphQL::Stitching::TypeResolver::ArgumentsTest < Minitest::Test + Argument = GraphQL::Stitching::TypeResolver::Argument + ObjectArgumentValue = GraphQL::Stitching::TypeResolver::ObjectArgumentValue + LiteralArgumentValue = GraphQL::Stitching::TypeResolver::LiteralArgumentValue + EnumArgumentValue = GraphQL::Stitching::TypeResolver::EnumArgumentValue + KeyArgumentValue = GraphQL::Stitching::TypeResolver::KeyArgumentValue class TestSchema < GraphQL::Schema class TestEnum < GraphQL::Schema::Enum @@ -86,7 +86,7 @@ def test_builds_flat_object_key_into_matching_input_object value: KeyArgumentValue.new(["slug"]), )] - assert_equal expected, GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("objectKey")) + assert_equal expected, GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("objectKey")) end def test_builds_nested_object_key_into_matching_input_objects @@ -120,7 +120,7 @@ def test_builds_nested_object_key_into_matching_input_objects ]), )] - assert_equal expected, GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("objectKey")) + assert_equal expected, GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("objectKey")) end def test_builds_nested_key_paths @@ -138,7 +138,7 @@ def test_builds_nested_key_paths ]), )] - assert_equal expected, GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("objectKey")) + assert_equal expected, GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("objectKey")) end def test_builds_object_list_keys_into_matching_inputs @@ -168,7 +168,7 @@ def test_builds_object_list_keys_into_matching_inputs ]), )] - assert_equal expected, GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("objectListKey")) + assert_equal expected, GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("objectListKey")) end def test_builds_objects_into_custom_scalar_with_no_typing @@ -197,64 +197,64 @@ def test_builds_objects_into_custom_scalar_with_no_typing ]), )] - assert_equal expected, GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("scalarKey")) + assert_equal expected, GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("scalarKey")) end def test_errors_for_building_objects_into_builtin_scalars assert_error "can only be built into custom scalar types" do template = "key: {slug: $.slug, namespace: $.namespace}" - GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("builtinScalarKey")) + GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("builtinScalarKey")) end end def test_errors_for_building_objects_into_non_object_non_scalars assert_error "can only be built into input object and scalar positions" do template = "key: {slug: $.slug, namespace: $.namespace}" - GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("enumKey")) + GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("enumKey")) end end def test_errors_building_invalid_root_keys assert_error "`invalid` is not a valid argument" do template = "key: {slug: $.slug, namespace: $.namespace}, invalid: true" - GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("objectKey")) + GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("objectKey")) end end def test_errors_building_invalid_object_keys assert_error "`invalid` is not a valid argument" do template = "key: {slug: $.slug, namespace: $.namespace, invalid: true}" - GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("objectKey")) + GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("objectKey")) end end def test_errors_omitting_a_required_root_argument assert_error "Required argument `key` has no input" do - GraphQL::Stitching::Resolver.parse_arguments_with_field(%|other:"test"|, get_field("objectKey")) + GraphQL::Stitching::TypeResolver.parse_arguments_with_field(%|other:"test"|, get_field("objectKey")) end end def test_errors_omitting_a_required_object_argument assert_error "Required argument `slug` has no input" do - GraphQL::Stitching::Resolver.parse_arguments_with_field(%|key: {namespace: $.namespace}|, get_field("objectKey")) + GraphQL::Stitching::TypeResolver.parse_arguments_with_field(%|key: {namespace: $.namespace}|, get_field("objectKey")) end end def test_errors_building_keys_into_non_list_arguments_for_list_fields assert_error "Cannot use repeatable key for `Query.objectListKey` in non-list argument `other`" do - GraphQL::Stitching::Resolver.parse_arguments_with_field(%|keys: {slug: $.slug} other: $.slug|, get_field("objectListKey")) + GraphQL::Stitching::TypeResolver.parse_arguments_with_field(%|keys: {slug: $.slug} other: $.slug|, get_field("objectListKey")) end end def test_errors_building_keys_into_list_arguments_for_non_list_fields assert_error "Cannot use non-repeatable key for `Query.objectKey` in list argument `list`" do - GraphQL::Stitching::Resolver.parse_arguments_with_field(%|key: {slug: $.slug}, list: $.slug|, get_field("objectKey")) + GraphQL::Stitching::TypeResolver.parse_arguments_with_field(%|key: {slug: $.slug}, list: $.slug|, get_field("objectKey")) end end def test_arguments_build_expected_value_structure template = "key: {slug: $.name, namespace: 'sol', nested:{slug: $.outer.name, namespace: $.outer.galaxy}}" - arg = GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("objectKey")).first + arg = GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("objectKey")).first origin_obj = { "_export_name" => "neptune", @@ -278,7 +278,7 @@ def test_arguments_build_expected_value_structure def test_arguments_build_primitive_keys template = "key: $.key, scope: 'foo', mode: YES" - args = GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("basicKey")) + args = GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("basicKey")) origin_obj = { "_export_key" => "123" } assert_equal ["123", "foo", "YES"], args.map { _1.build(origin_obj) } @@ -286,7 +286,7 @@ def test_arguments_build_primitive_keys def test_arguments_allows_wrapping_parenthesis template = "(key: $.key)" - args = GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("basicKey")) + args = GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("basicKey")) origin_obj = { "_export_key" => "123" } assert_equal ["123"], args.map { _1.build(origin_obj) } @@ -294,7 +294,7 @@ def test_arguments_allows_wrapping_parenthesis def test_prints_argument_object_structures template = "key: {slug: $.name, namespace: 'sol', nested: {slug: $.outer.name, namespace: $.outer.galaxy}}" - arg = GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("objectKey")).first + arg = GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("objectKey")).first assert_equal template, arg.to_definition assert_equal template.gsub("'", %|"|), arg.print @@ -303,7 +303,7 @@ def test_prints_argument_object_structures def test_prints_primitive_argument_types template = "key: $.key, scope: 'foo', mode: YES" - args = GraphQL::Stitching::Resolver.parse_arguments_with_field(template, get_field("basicKey")) + args = GraphQL::Stitching::TypeResolver.parse_arguments_with_field(template, get_field("basicKey")) assert_equal template, args.map(&:to_definition).join(", ") assert_equal template.gsub("'", %|"|), args.map(&:print).join(", ") @@ -334,7 +334,7 @@ def test_parse_arguments_with_type_defs value: LiteralArgumentValue.new("boom"), )] - assert_equal expected, GraphQL::Stitching::Resolver.parse_arguments_with_type_defs(template, type_defs) + assert_equal expected, GraphQL::Stitching::TypeResolver.parse_arguments_with_type_defs(template, type_defs) end def test_checks_primitive_values_for_presence_of_keys @@ -380,31 +380,31 @@ def test_checks_composite_values_for_presence_of_keys def test_verifies_key_insertion_paths_against_flat_key_selections arg = Argument.new(name: "id", value: KeyArgumentValue.new("id")) - assert arg.verify_key(GraphQL::Stitching::Resolver.parse_key("id")) + assert arg.verify_key(GraphQL::Stitching::TypeResolver.parse_key("id")) assert_error("Argument `id: $.id` cannot insert key `sfoo`") do - arg.verify_key(GraphQL::Stitching::Resolver.parse_key("sfoo")) + arg.verify_key(GraphQL::Stitching::TypeResolver.parse_key("sfoo")) end end def test_verifies_key_insertion_paths_against_nested_key_selections arg = Argument.new(name: "ownerId", value: KeyArgumentValue.new(["owner", "id"])) - assert arg.verify_key(GraphQL::Stitching::Resolver.parse_key("owner { id }")) + assert arg.verify_key(GraphQL::Stitching::TypeResolver.parse_key("owner { id }")) assert_error("Argument `ownerId: $.owner.id` cannot insert key `owner { sfoo }`") do - arg.verify_key(GraphQL::Stitching::Resolver.parse_key("owner { sfoo }")) + arg.verify_key(GraphQL::Stitching::TypeResolver.parse_key("owner { sfoo }")) end end def test_verifies_key_insertion_paths_for_typename_as_valid arg = Argument.new(name: "type", value: KeyArgumentValue.new("__typename")) - assert arg.verify_key(GraphQL::Stitching::Resolver.parse_key("id")) + assert arg.verify_key(GraphQL::Stitching::TypeResolver.parse_key("id")) end def test_no_key_verification_for_non_key_values arg = Argument.new(name: "secret", value: LiteralArgumentValue.new("boo")) - assert !arg.verify_key(GraphQL::Stitching::Resolver.parse_key("id")) + assert !arg.verify_key(GraphQL::Stitching::TypeResolver.parse_key("id")) end def test_verifies_key_insertion_paths_through_input_object_scopes @@ -426,7 +426,7 @@ def test_verifies_key_insertion_paths_through_input_object_scopes ]), ) - assert arg.verify_key(GraphQL::Stitching::Resolver.parse_key("id owner { id }")) + assert arg.verify_key(GraphQL::Stitching::TypeResolver.parse_key("id owner { id }")) end private diff --git a/test/graphql/stitching/resolver/keys_test.rb b/test/graphql/stitching/resolver/keys_test.rb index 1cb2f5ee..6db93ec8 100644 --- a/test/graphql/stitching/resolver/keys_test.rb +++ b/test/graphql/stitching/resolver/keys_test.rb @@ -2,23 +2,23 @@ require "test_helper" -class GraphQL::Stitching::Resolver::KeysTest < Minitest::Test - Key = GraphQL::Stitching::Resolver::Key - KeyFieldSet = GraphQL::Stitching::Resolver::KeyFieldSet - KeyField = GraphQL::Stitching::Resolver::KeyField - FieldNode = GraphQL::Stitching::Resolver::FieldNode +class GraphQL::Stitching::TypeResolver::KeysTest < Minitest::Test + Key = GraphQL::Stitching::TypeResolver::Key + KeyFieldSet = GraphQL::Stitching::TypeResolver::KeyFieldSet + KeyField = GraphQL::Stitching::TypeResolver::KeyField + FieldNode = GraphQL::Stitching::TypeResolver::FieldNode def test_formats_export_keys - assert_equal "_export_id", GraphQL::Stitching::Resolver.export_key("id") + assert_equal "_export_id", GraphQL::Stitching::TypeResolver.export_key("id") end def test_identifies_export_keys - assert GraphQL::Stitching::Resolver.export_key?("_export_id") - assert !GraphQL::Stitching::Resolver.export_key?("id") + assert GraphQL::Stitching::TypeResolver.export_key?("_export_id") + assert !GraphQL::Stitching::TypeResolver.export_key?("id") end def test_parses_key_with_locations - key = GraphQL::Stitching::Resolver.parse_key("id reference { id __typename }", ["a", "b"]) + key = GraphQL::Stitching::TypeResolver.parse_key("id reference { id __typename }", ["a", "b"]) expected = Key.new([ KeyField.new("id"), KeyField.new( @@ -35,21 +35,21 @@ def test_parses_key_with_locations def test_fulfills_key_set_uniqueness keys = [ - GraphQL::Stitching::Resolver.parse_key("id"), - GraphQL::Stitching::Resolver.parse_key("id"), - GraphQL::Stitching::Resolver.parse_key("sku id"), - GraphQL::Stitching::Resolver.parse_key("id sku"), - GraphQL::Stitching::Resolver.parse_key("ref { a b } c"), - GraphQL::Stitching::Resolver.parse_key("c ref { b a }"), + GraphQL::Stitching::TypeResolver.parse_key("id"), + GraphQL::Stitching::TypeResolver.parse_key("id"), + GraphQL::Stitching::TypeResolver.parse_key("sku id"), + GraphQL::Stitching::TypeResolver.parse_key("id sku"), + GraphQL::Stitching::TypeResolver.parse_key("ref { a b } c"), + GraphQL::Stitching::TypeResolver.parse_key("c ref { b a }"), ].uniq(&:to_definition) assert_equal ["id", "id sku", "c ref { a b }"], keys.map(&:to_definition) end def test_matches_basic_keys - key1 = GraphQL::Stitching::Resolver.parse_key("id") - key2 = GraphQL::Stitching::Resolver.parse_key("id") - key3 = GraphQL::Stitching::Resolver.parse_key("sku") + key1 = GraphQL::Stitching::TypeResolver.parse_key("id") + key2 = GraphQL::Stitching::TypeResolver.parse_key("id") + key3 = GraphQL::Stitching::TypeResolver.parse_key("sku") assert key1 == key2 assert key2 == key1 assert key1 != key3 @@ -57,10 +57,10 @@ def test_matches_basic_keys end def test_matches_key_sets - key1 = GraphQL::Stitching::Resolver.parse_key("id sku") - key2 = GraphQL::Stitching::Resolver.parse_key("sku id") - key3 = GraphQL::Stitching::Resolver.parse_key("id upc") - key4 = GraphQL::Stitching::Resolver.parse_key("id") + key1 = GraphQL::Stitching::TypeResolver.parse_key("id sku") + key2 = GraphQL::Stitching::TypeResolver.parse_key("sku id") + key3 = GraphQL::Stitching::TypeResolver.parse_key("id upc") + key4 = GraphQL::Stitching::TypeResolver.parse_key("id") assert key1 == key2 assert key2 == key1 assert key1 != key3 @@ -68,10 +68,10 @@ def test_matches_key_sets end def test_matches_nested_key_sets - key1 = GraphQL::Stitching::Resolver.parse_key("id ref { ns key }") - key2 = GraphQL::Stitching::Resolver.parse_key("ref { key ns } id") - key3 = GraphQL::Stitching::Resolver.parse_key("id ref { key }") - key4 = GraphQL::Stitching::Resolver.parse_key("ref { key ns }") + key1 = GraphQL::Stitching::TypeResolver.parse_key("id ref { ns key }") + key2 = GraphQL::Stitching::TypeResolver.parse_key("ref { key ns } id") + key3 = GraphQL::Stitching::TypeResolver.parse_key("id ref { key }") + key4 = GraphQL::Stitching::TypeResolver.parse_key("ref { key ns }") assert key1 == key2 assert key2 == key1 assert key1 != key3 @@ -79,16 +79,16 @@ def test_matches_nested_key_sets end def test_matches_nested_and_unnested_key_names_dont_match - key1 = GraphQL::Stitching::Resolver.parse_key("ref { key }") - key2 = GraphQL::Stitching::Resolver.parse_key("ref") + key1 = GraphQL::Stitching::TypeResolver.parse_key("ref { key }") + key2 = GraphQL::Stitching::TypeResolver.parse_key("ref") assert key1 != key2 assert key2 != key1 end def test_prints_a_basic_key - key1 = GraphQL::Stitching::Resolver.parse_key("id") - key2 = GraphQL::Stitching::Resolver.parse_key("ref id") - key3 = GraphQL::Stitching::Resolver.parse_key("ref { ns key } id") + key1 = GraphQL::Stitching::TypeResolver.parse_key("id") + key2 = GraphQL::Stitching::TypeResolver.parse_key("ref id") + key3 = GraphQL::Stitching::TypeResolver.parse_key("ref { ns key } id") assert_equal "id", key1.to_definition assert_equal "id ref", key2.to_definition @@ -97,18 +97,18 @@ def test_prints_a_basic_key def test_errors_for_non_field_keys assert_error("selections must be fields") do - GraphQL::Stitching::Resolver.parse_key("...{ id }") + GraphQL::Stitching::TypeResolver.parse_key("...{ id }") end end def test_errors_for_aliased_keys assert_error("may not specify aliases") do - GraphQL::Stitching::Resolver.parse_key("id: key") + GraphQL::Stitching::TypeResolver.parse_key("id: key") end end def test_formats_flat_export_nodes - key = GraphQL::Stitching::Resolver.parse_key("id") + key = GraphQL::Stitching::TypeResolver.parse_key("id") expected = [ FieldNode.build( field_alias: "_export_id", @@ -126,7 +126,7 @@ def test_formats_flat_export_nodes end def test_formats_nested_export_nodes - key = GraphQL::Stitching::Resolver.parse_key("ref { key } id") + key = GraphQL::Stitching::TypeResolver.parse_key("ref { key } id") expected = [ FieldNode.build( field_alias: "_export_id", @@ -165,7 +165,7 @@ def test_builds_keys_with_type_mapping | compose_definitions({ a: a, b: b }) do |composer| - field = GraphQL::Stitching::Resolver.parse_key_with_types( + field = GraphQL::Stitching::TypeResolver.parse_key_with_types( "test { id list { id } }", composer.subgraph_types_by_name_and_location["Test"], ).first @@ -195,7 +195,7 @@ def test_composite_keys_must_contain_inner_selections compose_definitions({ a: a, b: b }) do |composer| assert_error("Composite key fields must contain nested selections") do - GraphQL::Stitching::Resolver.parse_key_with_types( + GraphQL::Stitching::TypeResolver.parse_key_with_types( "test", composer.subgraph_types_by_name_and_location["Test"], ) @@ -219,12 +219,12 @@ def test_keys_must_be_fully_available_in_at_least_one_location compose_definitions({ a: a, b: b, c: c }) do |composer| ["id", "sku", "id sku", "id test { a }", "sku test { b }"].each do |key| - assert GraphQL::Stitching::Resolver.parse_key_with_types(key, composer.subgraph_types_by_name_and_location["Test"]) + assert GraphQL::Stitching::TypeResolver.parse_key_with_types(key, composer.subgraph_types_by_name_and_location["Test"]) end ["id test { b }", "sku test { a }", "test { a b }"].each do |key| assert_error("Key `#{key}` does not exist in any location") do - GraphQL::Stitching::Resolver.parse_key_with_types(key, composer.subgraph_types_by_name_and_location["Test"]) + GraphQL::Stitching::TypeResolver.parse_key_with_types(key, composer.subgraph_types_by_name_and_location["Test"]) end end end @@ -245,19 +245,19 @@ def test_keys_assign_locations | compose_definitions({ a: a, b: b, c: c }) do |composer| - k1 = GraphQL::Stitching::Resolver.parse_key_with_types("id", composer.subgraph_types_by_name_and_location["Test"]) + k1 = GraphQL::Stitching::TypeResolver.parse_key_with_types("id", composer.subgraph_types_by_name_and_location["Test"]) assert_equal ["a", "b"], k1.locations - k2 = GraphQL::Stitching::Resolver.parse_key_with_types("sku", composer.subgraph_types_by_name_and_location["Test"]) + k2 = GraphQL::Stitching::TypeResolver.parse_key_with_types("sku", composer.subgraph_types_by_name_and_location["Test"]) assert_equal ["b", "c"], k2.locations - k3 = GraphQL::Stitching::Resolver.parse_key_with_types("id test { a }", composer.subgraph_types_by_name_and_location["Test"]) + k3 = GraphQL::Stitching::TypeResolver.parse_key_with_types("id test { a }", composer.subgraph_types_by_name_and_location["Test"]) assert_equal ["a"], k3.locations - k4 = GraphQL::Stitching::Resolver.parse_key_with_types("id sku", composer.subgraph_types_by_name_and_location["Test"]) + k4 = GraphQL::Stitching::TypeResolver.parse_key_with_types("id sku", composer.subgraph_types_by_name_and_location["Test"]) assert_equal ["b"], k4.locations - k5 = GraphQL::Stitching::Resolver.parse_key_with_types("sku test { b }", composer.subgraph_types_by_name_and_location["Test"]) + k5 = GraphQL::Stitching::TypeResolver.parse_key_with_types("sku test { b }", composer.subgraph_types_by_name_and_location["Test"]) assert_equal ["c"], k5.locations end end diff --git a/test/graphql/stitching/supergraph_test.rb b/test/graphql/stitching/supergraph_test.rb index f0922f18..28c60503 100644 --- a/test/graphql/stitching/supergraph_test.rb +++ b/test/graphql/stitching/supergraph_test.rb @@ -84,27 +84,27 @@ class Query < GraphQL::Schema::Object RESOLVERS_MAP = { "Manufacturer" => [ - GraphQL::Stitching::Resolver.new( + GraphQL::Stitching::TypeResolver.new( location: "manufacturers", field: "manufacturer", - key: GraphQL::Stitching::Resolver.parse_key("id", FIELDS_MAP.dig("Manufacturer", "id")), - arguments: GraphQL::Stitching::Resolver.parse_arguments_with_type_defs("id: $.id", "id: ID"), + key: GraphQL::Stitching::TypeResolver.parse_key("id", FIELDS_MAP.dig("Manufacturer", "id")), + arguments: GraphQL::Stitching::TypeResolver.parse_arguments_with_type_defs("id: $.id", "id: ID"), ), ], "Product" => [ - GraphQL::Stitching::Resolver.new( + GraphQL::Stitching::TypeResolver.new( location: "products", field: "products", - key: GraphQL::Stitching::Resolver.parse_key("upc", FIELDS_MAP.dig("Product", "upc")), - arguments: GraphQL::Stitching::Resolver.parse_arguments_with_type_defs("upc: $.upc", "upc: ID"), + key: GraphQL::Stitching::TypeResolver.parse_key("upc", FIELDS_MAP.dig("Product", "upc")), + arguments: GraphQL::Stitching::TypeResolver.parse_arguments_with_type_defs("upc: $.upc", "upc: ID"), ), ], "Storefront" => [ - GraphQL::Stitching::Resolver.new( + GraphQL::Stitching::TypeResolver.new( location: "storefronts", field: "storefronts", - key: GraphQL::Stitching::Resolver.parse_key("id", FIELDS_MAP.dig("Storefront", "id")), - arguments: GraphQL::Stitching::Resolver.parse_arguments_with_type_defs("id: $.id", "id: ID"), + key: GraphQL::Stitching::TypeResolver.parse_key("id", FIELDS_MAP.dig("Storefront", "id")), + arguments: GraphQL::Stitching::TypeResolver.parse_arguments_with_type_defs("id: $.id", "id: ID"), ), ], }