Skip to content

Commit

Permalink
cleanup static config. (#128)
Browse files Browse the repository at this point in the history
  • Loading branch information
gmac authored Apr 6, 2024
1 parent 159eafc commit 7ed8d32
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 28 deletions.
33 changes: 5 additions & 28 deletions lib/graphql/stitching/composer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require_relative "./composer/base_validator"
require_relative "./composer/validate_interfaces"
require_relative "./composer/validate_boundaries"
require_relative "./composer/static_config"

module GraphQL
module Stitching
Expand Down Expand Up @@ -187,36 +188,12 @@ def prepare_locations_input(locations_input)
raise ComposerError, "The schema for `#{location}` location must be a GraphQL::Schema class."
end

input.fetch(:stitch, GraphQL::Stitching::EMPTY_ARRAY).each do |dir|
type = dir[:parent_type_name] ? schema.types[dir[:parent_type_name]] : schema.query
raise ComposerError, "Invalid stitch directive type `#{dir[:parent_type_name]}`" unless type

field = type.fields[dir[:field_name]]
raise ComposerError, "Invalid stitch directive field `#{dir[:field_name]}`" unless field

field_path = "#{location}.#{field.name}"
@stitch_directives[field_path] ||= []
@stitch_directives[field_path] << dir.slice(:key, :type_name)
if config = StaticConfig.extract_directive_assignments(schema, location, input[:stitch])
@stitch_directives.merge!(config)
end

federation_entity_type = schema.types["_Entity"]
if federation_entity_type && federation_entity_type.kind.union? && schema.query.fields["_entities"]&.type&.unwrap == federation_entity_type
schema.possible_types(federation_entity_type).each do |entity_type|
entity_type.directives.each do |directive|
next unless directive.graphql_name == "key"

key = directive.arguments.keyword_arguments.fetch(:fields).strip
raise ComposerError, "Composite federation keys are not supported." unless /^\w+$/.match?(key)

field_path = "#{location}._entities"
@stitch_directives[field_path] ||= []
@stitch_directives[field_path] << {
key: key,
type_name: entity_type.graphql_name,
federation: true,
}
end
end
if config = StaticConfig.extract_federation_entities(schema, location)
@stitch_directives.merge!(config)
end

schemas[location.to_s] = schema
Expand Down
61 changes: 61 additions & 0 deletions lib/graphql/stitching/composer/static_config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# frozen_string_literal: true

module GraphQL::Stitching
class Composer
class StaticConfig

ENTITY_TYPENAME = "_Entity"
ENTITIES_QUERY = "_entities"

class << self
def extract_directive_assignments(schema, location, assignments)
return nil unless assignments && assignments.any?

assignments.each_with_object({}) do |cfg, memo|
type = cfg[:parent_type_name] ? schema.get_type(cfg[:parent_type_name]) : schema.query
raise ComposerError, "Invalid stitch directive type `#{cfg[:parent_type_name]}`" unless type

field = type.get_field(cfg[:field_name])
raise ComposerError, "Invalid stitch directive field `#{cfg[:field_name]}`" unless field

field_path = "#{location}.#{field.name}"
memo[field_path] ||= []
memo[field_path] << cfg.slice(:key, :type_name)
end
end

def extract_federation_entities(schema, location)
return nil unless has_federation_entities?(schema)

result = {}
schema.possible_types(schema.get_type(ENTITY_TYPENAME)).each do |entity_type|
entity_type.directives.each do |directive|
next unless directive.graphql_name == "key"

key = directive.arguments.keyword_arguments.fetch(:fields).strip
raise ComposerError, "Composite federation keys are not supported." unless /^\w+$/.match?(key)

field_path = "#{location}._entities"
result[field_path] ||= []
result[field_path] << {
key: key,
type_name: entity_type.graphql_name,
federation: true,
}
end
end

result
end

private

def has_federation_entities?(schema)
entity_type = schema.get_type(ENTITY_TYPENAME)
entities_query = schema.query.get_field(ENTITIES_QUERY)
entity_type && entity_type.kind.union? && entities_query && entities_query.type.unwrap == entity_type
end
end
end
end
end

0 comments on commit 7ed8d32

Please sign in to comment.