apollo-federation 1.0.0 → 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 +4 -4
- data/CHANGELOG.md +35 -0
- data/README.md +2 -0
- data/lib/apollo-federation/entities_field.rb +10 -3
- data/lib/apollo-federation/federated_document_from_schema_definition.rb +12 -4
- data/lib/apollo-federation/has_directives.rb +2 -0
- data/lib/apollo-federation/schema.rb +64 -20
- data/lib/apollo-federation/service_field.rb +2 -1
- data/lib/apollo-federation/tracing/tracer.rb +7 -6
- data/lib/apollo-federation/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c06244e9136f28d4a4c15906ab176c9d4d83ea685c1b2a73bcac91d6f1ac8e65
|
4
|
+
data.tar.gz: f9f9eec152182226fe35fc07f97f7e4a787a7ba2cd45442f2725f8c7a593a28e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 451f1e7582fcbe3a85061755ef537678c819532879994584243c9ce9424883496d4ae9db79926dd25a7b5baab374395438d670e0c1967735ca31cf07519c5058
|
7
|
+
data.tar.gz: b118eda2b44fb44499745b4161cb75fc75dc59b59e29158d434b8152e23ce772b1b51c47820a8e4c9fb5c0275262b0a02d826dc1bfeda56ad3d4fac697fb3ab7
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,38 @@
|
|
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
|
+
|
8
|
+
## [1.0.4](https://github.com/Gusto/apollo-federation-ruby/compare/v1.0.3...v1.0.4) (2020-04-06)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* Fix spec to account for breaking change to graphql-ruby 1.10.0 ([#62](https://github.com/Gusto/apollo-federation-ruby/issues/62)) ([a631441](https://github.com/Gusto/apollo-federation-ruby/commit/a631441))
|
14
|
+
|
15
|
+
## [1.0.3](https://github.com/Gusto/apollo-federation-ruby/compare/v1.0.2...v1.0.3) (2020-03-25)
|
16
|
+
|
17
|
+
|
18
|
+
### Bug Fixes
|
19
|
+
|
20
|
+
* Make the tracer work with the new interpreter runtime ([#59](https://github.com/Gusto/apollo-federation-ruby/issues/59)) ([de4caf0](https://github.com/Gusto/apollo-federation-ruby/commit/de4caf0))
|
21
|
+
|
22
|
+
## [1.0.2](https://github.com/Gusto/apollo-federation-ruby/compare/v1.0.1...v1.0.2) (2020-02-19)
|
23
|
+
|
24
|
+
|
25
|
+
### Bug Fixes
|
26
|
+
|
27
|
+
* service field context ([#50](https://github.com/Gusto/apollo-federation-ruby/issues/50)) ([6dd1fe7](https://github.com/Gusto/apollo-federation-ruby/commit/6dd1fe7))
|
28
|
+
|
29
|
+
## [1.0.1](https://github.com/Gusto/apollo-federation-ruby/compare/v1.0.0...v1.0.1) (2020-01-29)
|
30
|
+
|
31
|
+
|
32
|
+
### Bug Fixes
|
33
|
+
|
34
|
+
* Send context to SDL generation / don't cache ([#45](https://github.com/Gusto/apollo-federation-ruby/issues/45)) ([9a29be1](https://github.com/Gusto/apollo-federation-ruby/commit/9a29be1))
|
35
|
+
|
1
36
|
# [1.0.0](https://github.com/Gusto/apollo-federation-ruby/compare/v0.5.1...v1.0.0) (2019-12-09)
|
2
37
|
|
3
38
|
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# apollo-federation
|
2
2
|
|
3
|
+
[](https://circleci.com/gh/Gusto/apollo-federation-ruby/tree/master)
|
4
|
+
|
3
5
|
This gem extends the [GraphQL Ruby](http://graphql-ruby.org/) gem to add support for creating an [Apollo Federation](https://www.apollographql.com/docs/apollo-server/federation/introduction/) schema.
|
4
6
|
|
5
7
|
## DISCLAIMER
|
@@ -13,7 +13,14 @@ module ApolloFederation
|
|
13
13
|
module ClassMethods
|
14
14
|
extend GraphQL::Schema::Member::HasFields
|
15
15
|
|
16
|
-
def define_entities_field(
|
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:
|
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
|
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
|
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
|
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,
|
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],
|
@@ -8,49 +8,93 @@ require 'apollo-federation/federated_document_from_schema_definition.rb'
|
|
8
8
|
module ApolloFederation
|
9
9
|
module Schema
|
10
10
|
def self.included(klass)
|
11
|
-
|
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
|
12
16
|
end
|
13
17
|
|
14
|
-
module
|
15
|
-
def
|
16
|
-
|
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
|
17
25
|
|
18
|
-
|
26
|
+
def federation_query(query_obj)
|
27
|
+
# Build the new query object with the '_service' field
|
28
|
+
if query_obj.nil?
|
19
29
|
base = GraphQL::Schema::Object
|
30
|
+
elsif Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('1.10.0')
|
31
|
+
base = query_obj
|
20
32
|
else
|
21
|
-
base =
|
33
|
+
base = query_obj.metadata[:type_class]
|
22
34
|
end
|
23
35
|
|
24
|
-
|
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?
|
25
39
|
graphql_name 'Query'
|
26
40
|
|
27
41
|
include EntitiesField
|
28
42
|
include ServiceField
|
29
43
|
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# TODO: Remove these once we drop support for graphql 1.9
|
48
|
+
module OneNineMethods
|
49
|
+
include CommonMethods
|
50
|
+
|
51
|
+
def to_graphql
|
52
|
+
orig_defn = super
|
53
|
+
@query_object = federation_query(query)
|
30
54
|
|
31
55
|
possible_entities = orig_defn.types.values.select do |type|
|
32
56
|
!type.introspection? && !type.default_scalar? && type.is_a?(GraphQL::ObjectType) &&
|
33
57
|
type.metadata[:federation_directives]&.any? { |directive| directive[:name] == 'key' }
|
34
58
|
end
|
59
|
+
@query_object.define_entities_field(possible_entities)
|
35
60
|
|
36
|
-
|
37
|
-
|
38
|
-
|
61
|
+
super
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
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
|
71
|
+
else
|
72
|
+
if !@federation_query_object
|
73
|
+
@federation_query_object = federation_query(@orig_query_object)
|
74
|
+
@federation_query_object.define_entities_field(schema_entities)
|
75
|
+
|
76
|
+
super(@federation_query_object)
|
39
77
|
end
|
40
|
-
|
41
|
-
|
42
|
-
federation_query.define_entities_field(entity_type)
|
78
|
+
|
79
|
+
super
|
43
80
|
end
|
81
|
+
end
|
44
82
|
|
45
|
-
|
83
|
+
private
|
46
84
|
|
47
|
-
|
48
|
-
|
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)
|
49
91
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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' }
|
54
98
|
end
|
55
99
|
end
|
56
100
|
end
|
@@ -10,7 +10,8 @@ module ApolloFederation
|
|
10
10
|
field(:_service, Service, null: false)
|
11
11
|
|
12
12
|
def _service
|
13
|
-
|
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
|
@@ -103,7 +103,7 @@ module ApolloFederation
|
|
103
103
|
# because we don't have the error `location` here.
|
104
104
|
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
105
105
|
def self.execute_field(data, &block)
|
106
|
-
context = data.fetch(:context) || data.fetch(:query).context
|
106
|
+
context = data.fetch(:context, nil) || data.fetch(:query).context
|
107
107
|
return block.call unless context && context[:tracing_enabled]
|
108
108
|
|
109
109
|
start_time_nanos = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
|
@@ -116,16 +116,17 @@ module ApolloFederation
|
|
116
116
|
|
117
117
|
end_time_nanos = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
|
118
118
|
|
119
|
-
#
|
119
|
+
# legacy runtime
|
120
120
|
if data.include?(:context)
|
121
121
|
path = context.path
|
122
122
|
field_name = context.field.graphql_name
|
123
123
|
field_type = context.field.type.to_s
|
124
124
|
parent_type = context.parent_type.graphql_name
|
125
|
-
else #
|
125
|
+
else # interpreter runtime
|
126
126
|
path = data.fetch(:path)
|
127
|
-
|
128
|
-
|
127
|
+
field = data.fetch(:field)
|
128
|
+
field_name = field.graphql_name
|
129
|
+
field_type = field.type.to_type_signature
|
129
130
|
parent_type = data.fetch(:owner).graphql_name
|
130
131
|
end
|
131
132
|
|
@@ -147,7 +148,7 @@ module ApolloFederation
|
|
147
148
|
# Optional Step 3:
|
148
149
|
# Overwrite the end times on the trace node if the resolver was lazy.
|
149
150
|
def self.execute_field_lazy(data, &block)
|
150
|
-
context = data.fetch(:context) || data.fetch(:query).context
|
151
|
+
context = data.fetch(:context, nil) || data.fetch(:query).context
|
151
152
|
return block.call unless context && context[:tracing_enabled]
|
152
153
|
|
153
154
|
begin
|
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.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Noa Elad
|
@@ -9,20 +9,20 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-05-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: graphql
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: 1.9.8
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- - "
|
25
|
+
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 1.9.8
|
28
28
|
- !ruby/object:Gem::Dependency
|