graphql-stitching 0.2.2 → 0.2.3
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/README.md +31 -2
- data/docs/supergraph.md +1 -1
- data/graphql-stitching.gemspec +1 -1
- data/lib/graphql/stitching/composer/validate_boundaries.rb +11 -1
- data/lib/graphql/stitching/supergraph.rb +2 -2
- data/lib/graphql/stitching/version.rb +1 -1
- data/lib/graphql/stitching.rb +50 -0
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a05f9ff15f40a886a20136cdaf5323cf37a59e7d98de27cc19cf7e600feb48e2
|
4
|
+
data.tar.gz: 7727f7394bb99abcb3c3a448f1ebf8b3bd5f9b7a2fd74e9bc741285f401a23cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8993da51f8bd18ec1e590727a24bcba8690831e006a1a3fc861cfaa83b9794b94f90fb0e458919d7997d67606ae8ece4acfdd8a3a0d6fe669e7971b01232cf3
|
7
|
+
data.tar.gz: 1032ed3279a98d1bc52db321a49a0a47d78dfb00cf9a8c922d1e77217ac837f8695c146908767ec398620f42a816f92eefc339d1fde970fe543904a6a30976f5
|
data/README.md
CHANGED
@@ -92,7 +92,7 @@ To facilitate this merging of types, stitching must know how to cross-reference
|
|
92
92
|
directive @stitch(key: String!) repeatable on FIELD_DEFINITION
|
93
93
|
```
|
94
94
|
|
95
|
-
This directive is applied to root queries where a merged type may be accessed in each location, and a `key` argument specifies a field needed from other locations to be used as a query argument.
|
95
|
+
This directive (or [static configuration](#sdl-based-schemas)) is applied to root queries where a merged type may be accessed in each location, and a `key` argument specifies a field needed from other locations to be used as a query argument.
|
96
96
|
|
97
97
|
```ruby
|
98
98
|
products_schema = <<~GRAPHQL
|
@@ -219,7 +219,7 @@ type Query {
|
|
219
219
|
}
|
220
220
|
```
|
221
221
|
|
222
|
-
The `@stitch` directive is also repeatable (_requires graphql-ruby v2.0.15_), allowing a single query to associate with multiple keys:
|
222
|
+
The `@stitch` directive is also repeatable (_requires graphql-ruby >= v2.0.15_), allowing a single query to associate with multiple keys:
|
223
223
|
|
224
224
|
```graphql
|
225
225
|
type Product {
|
@@ -251,6 +251,35 @@ class Query < GraphQL::Schema::Object
|
|
251
251
|
end
|
252
252
|
```
|
253
253
|
|
254
|
+
The `@stitch` directive can be exported from a class-based schema to an SDL string by calling `schema.to_definition`.
|
255
|
+
|
256
|
+
#### SDL-based schemas
|
257
|
+
|
258
|
+
A clean SDL string may also have stitching directives applied via static configuration using the `GraphQL::Stitching` module to build the SDL into a schema:
|
259
|
+
|
260
|
+
```ruby
|
261
|
+
sdl_string = <<~GRAPHQL
|
262
|
+
type Product {
|
263
|
+
id: ID!
|
264
|
+
upc: ID!
|
265
|
+
}
|
266
|
+
type Query {
|
267
|
+
productById(id: ID!): Product
|
268
|
+
productByUpc(upc: ID!): Product
|
269
|
+
}
|
270
|
+
GRAPHQL
|
271
|
+
|
272
|
+
decorated_schema = GraphQL::Stitching.schema_from_definition(sdl_string, stitch_directives: [
|
273
|
+
{ type_name: "Query", field_name: "productById", key: "id" },
|
274
|
+
{ type_name: "Query", field_name: "productByUpc", key: "upc" },
|
275
|
+
])
|
276
|
+
|
277
|
+
supergraph = GraphQL::Stitching::Composer.new(schemas: {
|
278
|
+
"products" => decorated_schema,
|
279
|
+
# ...
|
280
|
+
})
|
281
|
+
```
|
282
|
+
|
254
283
|
#### Custom directive names
|
255
284
|
|
256
285
|
The library is configured to use a `@stitch` directive by default. You may customize this by setting a new name during initialization:
|
data/docs/supergraph.md
CHANGED
@@ -30,7 +30,7 @@ end
|
|
30
30
|
|
31
31
|
### Export and caching
|
32
32
|
|
33
|
-
A Supergraph is designed to be composed, cached, and restored. Calling the `export` method will return an SDL (Schema Definition Language) print of the combined graph schema and a
|
33
|
+
A Supergraph is designed to be composed, cached, and restored. Calling the `export` method will return an SDL (Schema Definition Language) print of the combined graph schema and a delegation mapping hash. These can be persisted in any raw format that suits your stack:
|
34
34
|
|
35
35
|
```ruby
|
36
36
|
supergraph_sdl, delegation_map = supergraph.export
|
data/graphql-stitching.gemspec
CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
|
|
26
26
|
end
|
27
27
|
spec.require_paths = ['lib']
|
28
28
|
|
29
|
-
spec.add_runtime_dependency 'graphql', '
|
29
|
+
spec.add_runtime_dependency 'graphql', '>= 1.13.9'
|
30
30
|
|
31
31
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
32
32
|
spec.add_development_dependency 'rake', '~> 12.0'
|
@@ -67,7 +67,17 @@ module GraphQL
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def validate_as_shared(ctx, type, subschema_types_by_location)
|
70
|
-
expected_fields =
|
70
|
+
expected_fields = begin
|
71
|
+
type.fields.keys.sort
|
72
|
+
rescue StandardError => e
|
73
|
+
# bug with inherited interfaces in older versions of GraphQL
|
74
|
+
if type.interfaces.any? { _1.is_a?(GraphQL::Schema::LateBoundType) }
|
75
|
+
raise Composer::ComposerError, "Merged interface inheritance requires GraphQL >= v2.0.3"
|
76
|
+
else
|
77
|
+
raise e
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
71
81
|
subschema_types_by_location.each do |location, subschema_type|
|
72
82
|
if subschema_type.fields.keys.sort != expected_fields
|
73
83
|
raise Composer::ValidationError, "Shared type `#{type.graphql_name}` must have consistent fields across locations,
|
@@ -96,7 +96,7 @@ module GraphQL
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
|
-
#
|
99
|
+
# "Type" => ["location1", "location2", ...]
|
100
100
|
def locations_by_type
|
101
101
|
@locations_by_type ||= @locations_by_type_and_field.each_with_object({}) do |(type_name, fields), memo|
|
102
102
|
memo[type_name] = fields.values.flatten.uniq
|
@@ -104,7 +104,7 @@ module GraphQL
|
|
104
104
|
end
|
105
105
|
|
106
106
|
# collects all possible boundary keys for a given type
|
107
|
-
#
|
107
|
+
# ("Type") => ["id", ...]
|
108
108
|
def possible_keys_for_type(type_name)
|
109
109
|
@possible_keys_by_type[type_name] ||= begin
|
110
110
|
keys = @boundaries[type_name].map { _1["selection"] }
|
data/lib/graphql/stitching.rb
CHANGED
@@ -19,6 +19,56 @@ module GraphQL
|
|
19
19
|
def stitching_directive_names
|
20
20
|
[stitch_directive]
|
21
21
|
end
|
22
|
+
|
23
|
+
def schema_from_definition(sdl, stitch_directives:)
|
24
|
+
ast = GraphQL.parse(sdl)
|
25
|
+
|
26
|
+
if stitch_directives&.any?
|
27
|
+
directive_definition = ast.definitions.find do |d|
|
28
|
+
d.is_a?(GraphQL::Language::Nodes::DirectiveDefinition) && d.name == stitch_directive
|
29
|
+
end
|
30
|
+
|
31
|
+
if !directive_definition
|
32
|
+
directive_sdl = "directive @#{stitch_directive}(key: String!) repeatable on FIELD_DEFINITION"
|
33
|
+
directive_definition = GraphQL.parse(directive_sdl).definitions.first
|
34
|
+
ast.send(:merge!, { definitions: [directive_definition, *ast.definitions] })
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
stitch_directives.each do |config|
|
39
|
+
config[:type_name] ||= "Query"
|
40
|
+
|
41
|
+
type_node = ast.definitions.find do |d|
|
42
|
+
d.is_a?(GraphQL::Language::Nodes::ObjectTypeDefinition) && d.name == config[:type_name]
|
43
|
+
end
|
44
|
+
|
45
|
+
raise StitchingError, "invalid type name `#{config[:type_name]}`." unless type_node
|
46
|
+
|
47
|
+
field_node = type_node.fields.find do |f|
|
48
|
+
f.name == config[:field_name]
|
49
|
+
end
|
50
|
+
|
51
|
+
raise StitchingError, "invalid field name `#{config[:field_name]}`." unless field_node
|
52
|
+
|
53
|
+
field_node.send(:merge!, {
|
54
|
+
directives: [
|
55
|
+
*field_node.directives,
|
56
|
+
GraphQL::Language::Nodes::Directive.new(
|
57
|
+
arguments: [GraphQL::Language::Nodes::Argument.new(name: "key", value: config[:key])],
|
58
|
+
name: stitch_directive,
|
59
|
+
)
|
60
|
+
]
|
61
|
+
})
|
62
|
+
end
|
63
|
+
|
64
|
+
if GraphQL::Schema::BuildFromDefinition.method(:from_document).parameters.first.last == :document
|
65
|
+
# GraphQL v1.13.x
|
66
|
+
GraphQL::Schema::BuildFromDefinition.from_document(ast, default_resolve: nil)
|
67
|
+
else
|
68
|
+
# GraphQL v2
|
69
|
+
GraphQL::Schema::BuildFromDefinition.from_document(GraphQL::Schema, ast, default_resolve: nil)
|
70
|
+
end
|
71
|
+
end
|
22
72
|
end
|
23
73
|
end
|
24
74
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-stitching
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Greg MacWilliam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-02-
|
11
|
+
date: 2023-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.13.9
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.13.9
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|