Class: WCC::Contentful::Graphql::Federation::NamespacesTypes

Inherits:
Object
  • Object
show all
Defined in:
lib/wcc/contentful/graphql/federation/namespaces_types.rb

Overview

This GraphQL type definition wraps a type definition from an external schema and redefines it in our top-level schema, so that names do not clash. ex. “Campus” in the events schema becomes “Event_Campus”

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(namespace:) ⇒ NamespacesTypes

Returns a new instance of NamespacesTypes.



15
16
17
# File 'lib/wcc/contentful/graphql/federation/namespaces_types.rb', line 15

def initialize(namespace:)
  @namespace = namespace
end

Instance Attribute Details

#namespaceObject (readonly)

Returns the value of attribute namespace.



13
14
15
# File 'lib/wcc/contentful/graphql/federation/namespaces_types.rb', line 13

def namespace
  @namespace
end

Class Method Details

.registryObject



8
9
10
# File 'lib/wcc/contentful/graphql/federation/namespaces_types.rb', line 8

def registry
  @registry ||= {}
end

Instance Method Details

#namespaced(type) ⇒ Object

Gets the graphql type definition for the externally resolved field



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
# File 'lib/wcc/contentful/graphql/federation/namespaces_types.rb', line 20

def namespaced(type)
  return type if type.default_scalar?
  return namespaced(type.of_type).to_list_type if type.is_a?(GraphQL::ListType)
  return namespaced(type.of_type).to_non_null_type if type.is_a?(GraphQL::NonNullType)

  me = self
  ns = namespace
  typename = [namespace, type.to_s].compact.join('_')
  self.class.registry[typename] ||=
    if type.is_a?(GraphQL::UnionType)
      possible_types =
        type.possible_types.map { |t| me.namespaced(t) }
      GraphQL::UnionType.define do
        name typename
        possible_types possible_types
      end
    elsif type.is_a?(GraphQL::InputObjectType)
      GraphQL::InputObjectType.define do
        name typename
        type.arguments.each do |(name, arg)|
          argument name, me.namespaced(arg.type)
        end
      end
    elsif type.is_a?(GraphQL::ScalarType)
      GraphQL::ScalarType.define do
        name typename

        coerce_input type.method(:coerce_input)
        coerce_result type.method(:coerce_result)
      end
    elsif type.is_a?(GraphQL::ObjectType)
      GraphQL::ObjectType.define do
        name typename
        description "#{type.name} from remote#{ns ? ' ' + ns : ''}"

        type.fields.each do |(name, field_def)|
          field name, me.namespaced(field_def.type) do
            field_def.arguments.each do |(arg_name, arg)|
              argument arg_name, me.namespaced(arg.type)
            end

            resolve ->(obj, _args, _ctx) do
              # The object is a JSON response that came back from the
              # external schema.  Resolve the value by using the hash key.
              obj[name]
            end
          end
        end
      end
    else
      raise ArgumentError, "Cannot namespace type #{type} (#{type.class})"
    end
end