apollo-federation 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9162a13344ba2374500711c42e7a3ae210bc12ba29747ab421e7b8bb2a8c36e4
4
- data.tar.gz: 963f3b9efabca3efb67617598be416b6a0f6aa15bd630b25749093bf40b0bd6e
3
+ metadata.gz: c06244e9136f28d4a4c15906ab176c9d4d83ea685c1b2a73bcac91d6f1ac8e65
4
+ data.tar.gz: f9f9eec152182226fe35fc07f97f7e4a787a7ba2cd45442f2725f8c7a593a28e
5
5
  SHA512:
6
- metadata.gz: 7a6a6ed04335cf873ba2a8589058d6960a4e1be29cc97deafab809c6bce682d7c66256290d56663b2e2f7bd5215e405f3c1a655f723494dfd1e39a9b97ded380
7
- data.tar.gz: 0bcceb1c673ecbb8c1d934219f29364433b7bd4208bf6b9a69bfe465f732cb531680637dd7258f7e6f948527f5c8f8cd24b6a75f6f49d75918013db4e9ec929d
6
+ metadata.gz: 451f1e7582fcbe3a85061755ef537678c819532879994584243c9ce9424883496d4ae9db79926dd25a7b5baab374395438d670e0c1967735ca31cf07519c5058
7
+ data.tar.gz: b118eda2b44fb44499745b4161cb75fc75dc59b59e29158d434b8152e23ce772b1b51c47820a8e4c9fb5c0275262b0a02d826dc1bfeda56ad3d4fac697fb3ab7
@@ -1,3 +1,10 @@
1
+ # [1.1.0](https://github.com/Gusto/apollo-federation-ruby/compare/v1.0.4...v1.1.0) (2020-05-27)
2
+
3
+
4
+ ### Features
5
+
6
+ * Add support for interpreter runtime ([#65](https://github.com/Gusto/apollo-federation-ruby/issues/65)) ([1957da0](https://github.com/Gusto/apollo-federation-ruby/commit/1957da0))
7
+
1
8
  ## [1.0.4](https://github.com/Gusto/apollo-federation-ruby/compare/v1.0.3...v1.0.4) (2020-04-06)
2
9
 
3
10
 
@@ -13,7 +13,14 @@ module ApolloFederation
13
13
  module ClassMethods
14
14
  extend GraphQL::Schema::Member::HasFields
15
15
 
16
- def define_entities_field(entity_type)
16
+ def define_entities_field(possible_entities)
17
+ # If there are any "entities", define the Entity union and and the Query._entities field
18
+ return if possible_entities.empty?
19
+
20
+ entity_type = Class.new(Entity) do
21
+ possible_types(*possible_entities)
22
+ end
23
+
17
24
  field(:_entities, [entity_type, null: true], null: false) do
18
25
  argument :representations, [Any], required: true
19
26
  extension(EntityTypeResolutionExtension)
@@ -32,8 +39,8 @@ module ApolloFederation
32
39
  ' but no object type of that name was found in the schema'
33
40
  end
34
41
 
35
- # TODO: Handle non-class types?
36
- type_class = type.metadata[:type_class]
42
+ # TODO: What if the type is an interface?
43
+ type_class = type.is_a?(GraphQL::ObjectType) ? type.metadata[:type_class] : type
37
44
  if type_class.respond_to?(:resolve_reference)
38
45
  result = type_class.resolve_reference(reference, context)
39
46
  else
@@ -23,17 +23,17 @@ module ApolloFederation
23
23
  end
24
24
  federation_fields.each { |field| object_node = object_node.delete_child(field) }
25
25
  end
26
- merge_directives(object_node, object_type.metadata[:federation_directives])
26
+ merge_directives(object_node, object_type)
27
27
  end
28
28
 
29
29
  def build_interface_type_node(interface_type)
30
30
  field_node = super
31
- merge_directives(field_node, interface_type.metadata[:federation_directives])
31
+ merge_directives(field_node, interface_type)
32
32
  end
33
33
 
34
34
  def build_field_node(field_type)
35
35
  field_node = super
36
- merge_directives(field_node, field_type.metadata[:federation_directives])
36
+ merge_directives(field_node, field_type)
37
37
  end
38
38
 
39
39
  def build_type_definition_nodes(types)
@@ -53,7 +53,15 @@ module ApolloFederation
53
53
  type == warden.root_type_for_operation('query')
54
54
  end
55
55
 
56
- def merge_directives(node, directives)
56
+ def merge_directives(node, type)
57
+ if type.is_a?(ApolloFederation::HasDirectives)
58
+ directives = type.federation_directives
59
+ elsif type.is_a?(GraphQL::Define::InstanceDefinable)
60
+ directives = type.metadata[:federation_directives]
61
+ else
62
+ directives = []
63
+ end
64
+
57
65
  (directives || []).each do |directive|
58
66
  node = node.merge_directive(
59
67
  name: directive[:name],
@@ -2,6 +2,8 @@
2
2
 
3
3
  module ApolloFederation
4
4
  module HasDirectives
5
+ attr_reader :federation_directives
6
+
5
7
  def add_directive(name:, arguments: nil)
6
8
  @federation_directives ||= []
7
9
  @federation_directives << { name: name, arguments: arguments }
@@ -8,52 +8,94 @@ require 'apollo-federation/federated_document_from_schema_definition.rb'
8
8
  module ApolloFederation
9
9
  module Schema
10
10
  def self.included(klass)
11
- klass.extend(ClassMethods)
11
+ if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('1.10.0')
12
+ klass.extend(OneTenMethods)
13
+ else
14
+ klass.extend(OneNineMethods)
15
+ end
16
+ end
17
+
18
+ module CommonMethods
19
+ def federation_sdl(context: nil)
20
+ document_from_schema = FederatedDocumentFromSchemaDefinition.new(self, context: context)
21
+ GraphQL::Language::Printer.new.print(document_from_schema.document)
22
+ end
23
+
24
+ private
25
+
26
+ def federation_query(query_obj)
27
+ # Build the new query object with the '_service' field
28
+ if query_obj.nil?
29
+ base = GraphQL::Schema::Object
30
+ elsif Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('1.10.0')
31
+ base = query_obj
32
+ else
33
+ base = query_obj.metadata[:type_class]
34
+ end
35
+
36
+ Class.new(base) do
37
+ # TODO: Maybe the name should inherit from the original Query name
38
+ # Or MAYBE we should just modify the original class?
39
+ graphql_name 'Query'
40
+
41
+ include EntitiesField
42
+ include ServiceField
43
+ end
44
+ end
12
45
  end
13
46
 
14
- module ClassMethods
47
+ # TODO: Remove these once we drop support for graphql 1.9
48
+ module OneNineMethods
49
+ include CommonMethods
50
+
15
51
  def to_graphql
16
52
  orig_defn = super
53
+ @query_object = federation_query(query)
17
54
 
18
55
  possible_entities = orig_defn.types.values.select do |type|
19
56
  !type.introspection? && !type.default_scalar? && type.is_a?(GraphQL::ObjectType) &&
20
57
  type.metadata[:federation_directives]&.any? { |directive| directive[:name] == 'key' }
21
58
  end
22
-
23
- @query_object = federation_query
24
-
25
- if !possible_entities.empty?
26
- entity_type = Class.new(Entity) do
27
- possible_types(*possible_entities)
28
- end
29
- # TODO: Should/can we encapsulate all of this inside the module? What's the best/most Ruby
30
- # way to split this out?
31
- @query_object.define_entities_field(entity_type)
32
- end
59
+ @query_object.define_entities_field(possible_entities)
33
60
 
34
61
  super
35
62
  end
63
+ end
36
64
 
37
- def federation_query
38
- if query.nil?
39
- base = GraphQL::Schema::Object
40
- elsif Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('1.10.0')
41
- base = query
65
+ module OneTenMethods
66
+ include CommonMethods
67
+
68
+ def query(new_query_object = nil)
69
+ if new_query_object
70
+ @orig_query_object = new_query_object
42
71
  else
43
- base = query.metadata[:type_class]
44
- end
72
+ if !@federation_query_object
73
+ @federation_query_object = federation_query(@orig_query_object)
74
+ @federation_query_object.define_entities_field(schema_entities)
45
75
 
46
- Class.new(base) do
47
- graphql_name 'Query'
76
+ super(@federation_query_object)
77
+ end
48
78
 
49
- include EntitiesField
50
- include ServiceField
79
+ super
51
80
  end
52
81
  end
53
82
 
54
- def federation_sdl(context: nil)
55
- document_from_schema = FederatedDocumentFromSchemaDefinition.new(self, context: context)
56
- GraphQL::Language::Printer.new.print(document_from_schema.document)
83
+ private
84
+
85
+ def schema_entities
86
+ # Create a temporary schema that inherits from this one to extract the types
87
+ types_schema = Class.new(self)
88
+ # Add the original query objects to the types. We have to use orphan_types here to avoid
89
+ # infinite recursion
90
+ types_schema.orphan_types(@orig_query_object)
91
+
92
+ # Walk through all of the types and determine which ones are entities (any type with a
93
+ # "key" directive)
94
+ types_schema.types.values.select do |type|
95
+ # TODO: Interfaces can have a key...
96
+ !type.introspection? && type.include?(ApolloFederation::Object) &&
97
+ type.federation_directives&.any? { |directive| directive[:name] == 'key' }
98
+ end
57
99
  end
58
100
  end
59
101
  end
@@ -10,7 +10,8 @@ module ApolloFederation
10
10
  field(:_service, Service, null: false)
11
11
 
12
12
  def _service
13
- { sdl: context.schema.class.federation_sdl(context: context) }
13
+ schema_class = context.schema.is_a?(GraphQL::Schema) ? context.schema.class : context.schema
14
+ { sdl: schema_class.federation_sdl(context: context) }
14
15
  end
15
16
  end
16
17
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ApolloFederation
4
- VERSION = '1.0.4'
4
+ VERSION = '1.1.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apollo-federation
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Noa Elad
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-04-06 00:00:00.000000000 Z
12
+ date: 2020-05-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: graphql