graphql-stitching 1.4.0 → 1.4.2
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 +12 -6
- data/docs/mechanics.md +2 -2
- data/lib/graphql/stitching/composer/validate_resolvers.rb +4 -2
- data/lib/graphql/stitching/composer.rb +2 -2
- data/lib/graphql/stitching/planner.rb +1 -1
- data/lib/graphql/stitching/resolver/keys.rb +1 -1
- data/lib/graphql/stitching/supergraph.rb +5 -1
- data/lib/graphql/stitching/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b81b29cdab4287ba09d6081595b83b4edcc96f0921790483f44d53ff946fb441
|
4
|
+
data.tar.gz: 39c3351dbb4a712aa4f43006017660a961a2056b82b96a5a14b3110b1ecfad44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d376c15fa17088797be0b2f7ab42a94cf24050f68b37640aac88cc13a526d56f0ee366290b246e4cc6838a60050b9d9073610366cb7ad5bdb0a9a3435e688dd4
|
7
|
+
data.tar.gz: 6a4fda5651bdd8794f59497e32bb9421c1d3f931a706483b55088597efdc9fe0bb1166dca16a66832c4ded42a21c89de2a7a8f2dc36cfb51bc44cfd40df9c4da
|
data/README.md
CHANGED
@@ -101,7 +101,7 @@ This directive (or [static configuration](#sdl-based-schemas)) is applied to roo
|
|
101
101
|
|
102
102
|
```ruby
|
103
103
|
products_schema = <<~GRAPHQL
|
104
|
-
directive @stitch(key: String
|
104
|
+
directive @stitch(key: String!, arguments: String) repeatable on FIELD_DEFINITION
|
105
105
|
|
106
106
|
type Product {
|
107
107
|
id: ID!
|
@@ -114,7 +114,7 @@ products_schema = <<~GRAPHQL
|
|
114
114
|
GRAPHQL
|
115
115
|
|
116
116
|
catalog_schema = <<~GRAPHQL
|
117
|
-
directive @stitch(key: String
|
117
|
+
directive @stitch(key: String!, arguments: String) repeatable on FIELD_DEFINITION
|
118
118
|
|
119
119
|
type Product {
|
120
120
|
id: ID!
|
@@ -226,7 +226,7 @@ type Query {
|
|
226
226
|
}
|
227
227
|
```
|
228
228
|
|
229
|
-
Key insertions are prefixed by `$` and specify a dot-notation path to any selections made by the resolver
|
229
|
+
Key insertions are prefixed by `$` and specify a dot-notation path to any selections made by the resolver key, or `__typename`. This syntax allows sending multiple arguments that intermix stitching keys with complex input shapes and other static values:
|
230
230
|
|
231
231
|
```graphql
|
232
232
|
type Product {
|
@@ -237,10 +237,14 @@ input EntityKey {
|
|
237
237
|
id: ID!
|
238
238
|
type: String!
|
239
239
|
}
|
240
|
+
enum EntitySource {
|
241
|
+
DATABASE
|
242
|
+
CACHE
|
243
|
+
}
|
240
244
|
|
241
245
|
type Query {
|
242
|
-
entities(keys: [EntityKey!]!, source:
|
243
|
-
@stitch(key: "id", arguments: "keys: { id: $.id, type: $.__typename }, source:
|
246
|
+
entities(keys: [EntityKey!]!, source: EntitySource = DATABASE): [Entity]!
|
247
|
+
@stitch(key: "id", arguments: "keys: { id: $.id, type: $.__typename }, source: CACHE")
|
244
248
|
}
|
245
249
|
```
|
246
250
|
|
@@ -265,6 +269,7 @@ input CustomFieldLookup {
|
|
265
269
|
ownerType: String!
|
266
270
|
key: String!
|
267
271
|
}
|
272
|
+
|
268
273
|
type Query {
|
269
274
|
customFields(lookups: [CustomFieldLookup!]!): [CustomField]! @stitch(
|
270
275
|
key: "owner { id type } key",
|
@@ -320,6 +325,7 @@ class StitchingResolver < GraphQL::Schema::Directive
|
|
320
325
|
locations FIELD_DEFINITION
|
321
326
|
repeatable true
|
322
327
|
argument :key, String, required: true
|
328
|
+
argument :arguments, String, required: false
|
323
329
|
end
|
324
330
|
|
325
331
|
class Query < GraphQL::Schema::Object
|
@@ -354,7 +360,7 @@ supergraph = GraphQL::Stitching::Composer.new.perform({
|
|
354
360
|
executable: ->() { ... },
|
355
361
|
stitch: [
|
356
362
|
{ field_name: "productById", key: "id" },
|
357
|
-
{ field_name: "productBySku", key: "sku" },
|
363
|
+
{ field_name: "productBySku", key: "sku", arguments: "mySku: $.sku" },
|
358
364
|
]
|
359
365
|
},
|
360
366
|
# ...
|
data/docs/mechanics.md
CHANGED
@@ -90,7 +90,7 @@ class GraphQlController
|
|
90
90
|
variables: params[:variables],
|
91
91
|
operation_name: params[:operation_name]
|
92
92
|
)
|
93
|
-
end
|
93
|
+
end
|
94
94
|
end
|
95
95
|
```
|
96
96
|
|
@@ -345,4 +345,4 @@ type Query {
|
|
345
345
|
}
|
346
346
|
```
|
347
347
|
|
348
|
-
In this graph, `Widget` is a merged type without a resolver query in location C. This works because all of its fields are resolvable in other locations; that means location C can provide outbound representations of this type without ever needing to resolve inbound requests for it. Outbound types do still require a shared key field (such as `id` above) that allow them to join with data in other resolver locations (such as `price` above).
|
348
|
+
In this graph, `Widget` is a merged type without a resolver query in location C. This works because all of its fields are resolvable in other locations; that means location C can provide outbound representations of this type without ever needing to resolve inbound requests for it. Outbound types do still require a shared key field (such as `id` above) that allow them to join with data in other resolver locations (such as `price` above). Support for this pattern is limited to single-field keys, [composite keys](../README.md#composite-type-keys) require a resolver definition.
|
@@ -55,8 +55,10 @@ module GraphQL::Stitching
|
|
55
55
|
end
|
56
56
|
|
57
57
|
# All locations of a merged type must include at least one resolver key
|
58
|
-
supergraph.fields_by_type_and_location[type.graphql_name].
|
59
|
-
|
58
|
+
supergraph.fields_by_type_and_location[type.graphql_name].each do |location, field_names|
|
59
|
+
has_resolver_key = resolver_keys.any? { _1.locations.include?(location) }
|
60
|
+
has_primitive_match = resolver_keys.any? { field_names.include?(_1.primitive_name) }
|
61
|
+
unless has_resolver_key || has_primitive_match
|
60
62
|
raise ValidationError, "A resolver key is required for `#{type.graphql_name}` in #{location} to join with other locations."
|
61
63
|
end
|
62
64
|
end
|
@@ -557,7 +557,7 @@ module GraphQL
|
|
557
557
|
argument = if subgraph_field.arguments.size == 1
|
558
558
|
subgraph_field.arguments.values.first
|
559
559
|
else
|
560
|
-
subgraph_field.arguments[key.
|
560
|
+
subgraph_field.arguments[key.primitive_name]
|
561
561
|
end
|
562
562
|
|
563
563
|
unless argument
|
@@ -565,7 +565,7 @@ module GraphQL
|
|
565
565
|
"An argument mapping is required for unmatched names and composite keys."
|
566
566
|
end
|
567
567
|
|
568
|
-
"#{argument.graphql_name}: $.#{key.
|
568
|
+
"#{argument.graphql_name}: $.#{key.primitive_name}"
|
569
569
|
end
|
570
570
|
|
571
571
|
arguments = Resolver.parse_arguments_with_field(arguments_format, subgraph_field)
|
@@ -244,6 +244,7 @@ module GraphQL
|
|
244
244
|
fragment = @request.fragment_definitions[node.name]
|
245
245
|
next unless @supergraph.locations_by_type[fragment.type.name].include?(current_location)
|
246
246
|
|
247
|
+
requires_typename = true
|
247
248
|
fragment_type = @supergraph.memoized_schema_types[fragment.type.name]
|
248
249
|
is_same_scope = fragment_type == parent_type
|
249
250
|
selection_set = is_same_scope ? locale_selections : []
|
@@ -251,7 +252,6 @@ module GraphQL
|
|
251
252
|
|
252
253
|
unless is_same_scope
|
253
254
|
locale_selections << GraphQL::Language::Nodes::InlineFragment.new(type: fragment.type, selections: selection_set)
|
254
|
-
requires_typename = true
|
255
255
|
end
|
256
256
|
|
257
257
|
else
|
@@ -147,7 +147,11 @@ module GraphQL
|
|
147
147
|
def possible_keys_for_type_and_location(type_name, location)
|
148
148
|
possible_keys_by_type = @possible_keys_by_type_and_location[type_name] ||= {}
|
149
149
|
possible_keys_by_type[location] ||= possible_keys_for_type(type_name).select do |key|
|
150
|
-
key.locations.include?(location)
|
150
|
+
next true if key.locations.include?(location)
|
151
|
+
|
152
|
+
# Outbound-only locations without resolver queries may dynamically match primitive keys
|
153
|
+
location_fields = fields_by_type_and_location[type_name][location] || GraphQL::Stitching::EMPTY_ARRAY
|
154
|
+
location_fields.include?(key.primitive_name)
|
151
155
|
end
|
152
156
|
end
|
153
157
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-stitching
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Greg MacWilliam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|