elasticgraph-apollo 1.1.0 → 1.2.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: 052a25ea05ffde8d36f52b110e035b5f85d1648cdc11084a52ab440fb277e6af
4
- data.tar.gz: 779198f684fe454c3ee6bfcd0b0a2dbe3cb4ef99f48cb47519f87c54e584d4aa
3
+ metadata.gz: 19e71c178b6179ade55d78184f3dd0bcb61911ad63d83c5ea2cf46e5784169fc
4
+ data.tar.gz: ff49d9a6eb9ffc836bc4af77963d562ef6774a0020a1af62f779d9ececac13e5
5
5
  SHA512:
6
- metadata.gz: 4a4f0e50b66c69ee7457f7fc908d0ea3e11c0c1c7eff65f864ec9287d0724d1c463cdb557be4dab300c2dadc851bc9a97e3c1fb17817809055c7c701d30f5c7a
7
- data.tar.gz: c6f247530c8afeb1a872a77723875707d079f37ed2226f3ad851fc65bc178e2b23b58b20e594ad6fc738244998bdfa212c5e1d5d7f0f148bc493d3cb1bfcd0d1
6
+ metadata.gz: a62e330762b3defc799ec2a6ca23d6329e15ffaf942bd95c9f465f0a9afee027608c0b5a47dd26aefabd3ffe93106d5148436b0b40a28690b1f783ec68d478b2
7
+ data.tar.gz: 950749b69754f09e493f53a8033c69052a2b4fd41b5845db89f1b9dde0cdeeb079d7ea2f0e22ef1b2580c3236831d5b6cf921925e7974f187360cd867f10ced0
@@ -67,7 +67,7 @@ module ElasticGraph
67
67
 
68
68
  # Builds a datastore query for the given specific representation.
69
69
  def build_query(adapter, representations, query_attributes)
70
- return nil unless adapter.indexed?
70
+ return nil unless adapter.root_document_type?
71
71
 
72
72
  type = adapter.type
73
73
  query = @datastore_query_builder.new_query(search_index_definitions: type.search_index_definitions, **query_attributes)
@@ -190,7 +190,7 @@ module ElasticGraph
190
190
  hit if hit && match?(representation.other_fields, hit.payload)
191
191
  end
192
192
 
193
- def indexed?
193
+ def root_document_type?
194
194
  true
195
195
  end
196
196
 
@@ -268,7 +268,7 @@ module ElasticGraph
268
268
  end
269
269
  end
270
270
 
271
- def indexed?
271
+ def root_document_type?
272
272
  true
273
273
  end
274
274
 
@@ -294,7 +294,7 @@ module ElasticGraph
294
294
  self
295
295
  end
296
296
 
297
- # :nocov: -- these methods are not called on an adapter when `indexed?` returns `false`.
297
+ # :nocov: -- these methods are not called on an adapter when `root_document_type?` returns `false`.
298
298
  def customize_query(query, representations)
299
299
  nil
300
300
  end
@@ -308,7 +308,7 @@ module ElasticGraph
308
308
  representation.representation_hash
309
309
  end
310
310
 
311
- def indexed?
311
+ def root_document_type?
312
312
  false
313
313
  end
314
314
  end
@@ -22,7 +22,7 @@ module ElasticGraph
22
22
  # * {Apollo::SchemaDefinition} is an extension used while defining an ElasticGraph schema. It includes all schema elements that are part
23
23
  # of the Apollo spec, including `_Entity` and the various directives.
24
24
  # * {Apollo::GraphQL} is an extension used by `elasticgraph-graphql` to support queries against Apollo's subgraph schema additions (e.g.
25
- # `_service` and `_entities`). It includes [reference resolvers](https://www.apollographql.com/docs/federation/entities/#2-define-a-reference-resolver)
25
+ # `_service` and `_entities`). It includes [reference resolvers](https://www.apollographql.com/docs/graphos/schema-design/federated-schemas/entities/intro#2-define-a-reference-resolver)
26
26
  # for all indexed types in your schema.
27
27
  #
28
28
  # To use `elasticgraph-apollo`, simply use {Apollo::SchemaDefinition::APIExtension} as a schema definition extension module. The GraphQL
@@ -336,45 +336,59 @@ module ElasticGraph
336
336
  end
337
337
  end
338
338
 
339
- entity_types = state.object_types_by_name.values.select do |object_type|
340
- object_type.directives.any? do |directive|
341
- directive.name == "key" && directive.arguments.fetch(:resolvable, true)
339
+ # Defer @key directive addition and _Entity union creation to a follow-up callback.
340
+ # This ensures types created by other after_user_definition_complete callbacks
341
+ # (e.g. dynamically derived aggregation types) exist before we iterate over them.
342
+ # This works because state.user_definition_complete_callbacks is a plain Array
343
+ # iterated with #each in Results#after_initialize — appending a new callback here
344
+ # causes it to be processed after all previously registered callbacks.
345
+ state.after_user_definition_complete do
346
+ # Add @key directives to all root document types with an id field.
347
+ state.object_types_by_name.values
348
+ .grep(ElasticGraph::SchemaDefinition::SchemaElements::ObjectType) # : ::Array[::ElasticGraph::SchemaDefinition::SchemaElements::ObjectType & ObjectTypeExtension]
349
+ .select { |object_type| object_type.root_document_type? && object_type.graphql_fields_by_name.key?("id") }
350
+ .each { |object_type| object_type.apollo_key fields: "id" }
351
+
352
+ entity_types = state.object_types_by_name.values.select do |object_type|
353
+ object_type.directives.any? do |directive|
354
+ directive.name == "key" && directive.arguments.fetch(:resolvable, true)
355
+ end
342
356
  end
343
- end
344
-
345
- validate_entity_types_can_all_be_resolved(entity_types)
346
-
347
- entity_type_names = entity_types
348
- # As per the GraphQL spec[1], only object types can be in a union, and interface
349
- # types cannot be in a union. The GraphQL gem has validation[2] for this and will raise
350
- # an error if we violate it, so we must filter to only object types here.
351
- #
352
- # [1] https://spec.graphql.org/October2021/#sec-Unions.Type-Validation
353
- # [2] https://github.com/rmosolgo/graphql-ruby/pull/3024
354
- .grep(ElasticGraph::SchemaDefinition::SchemaElements::ObjectType)
355
- .map(&:name)
356
-
357
- unless entity_type_names.empty?
358
- apollo_union_type "_Entity" do |t|
359
- t.extend EntityTypeExtension
360
- t.documentation <<~EOS
361
- A union type required by the [Apollo Federation subgraph
362
- spec](https://www.apollographql.com/docs/federation/subgraph-spec/#union-_entity):
363
-
364
- > **⚠️ This union type is generated dynamically based on the input subgraph schema!**
365
- >
366
- > This union's possible types must include all entities that the subgraph defines.
367
- > It's the return type of the `Query._entities` field, which the graph router uses
368
- > to directly access a subgraph's entity fields.
369
- >
370
- > For details, see [Defining the `_Entity` union](https://www.apollographql.com/docs/federation/subgraph-spec/#defining-the-_entity-union).
371
357
 
372
- In an ElasticGraph schema, this is a union of all indexed types.
373
-
374
- Not intended for use by clients other than Apollo.
375
- EOS
358
+ validate_entity_types_can_all_be_resolved(entity_types)
359
+
360
+ entity_type_names = entity_types
361
+ # As per the GraphQL spec[1], only object types can be in a union, and interface
362
+ # types cannot be in a union. The GraphQL gem has validation[2] for this and will raise
363
+ # an error if we violate it, so we must filter to only object types here.
364
+ #
365
+ # [1] https://spec.graphql.org/October2021/#sec-Unions.Type-Validation
366
+ # [2] https://github.com/rmosolgo/graphql-ruby/pull/3024
367
+ .grep(ElasticGraph::SchemaDefinition::SchemaElements::ObjectType)
368
+ .map(&:name)
369
+
370
+ unless entity_type_names.empty?
371
+ apollo_union_type "_Entity" do |t|
372
+ t.extend EntityTypeExtension
373
+ t.documentation <<~EOS
374
+ A union type required by the [Apollo Federation subgraph
375
+ spec](https://www.apollographql.com/docs/federation/subgraph-spec/#union-_entity):
376
+
377
+ > **⚠️ This union type is generated dynamically based on the input subgraph schema!**
378
+ >
379
+ > This union's possible types must include all entities that the subgraph defines.
380
+ > It's the return type of the `Query._entities` field, which the graph router uses
381
+ > to directly access a subgraph's entity fields.
382
+ >
383
+ > For details, see [Defining the `_Entity` union](https://www.apollographql.com/docs/federation/subgraph-spec/#defining-the-_entity-union).
384
+
385
+ In an ElasticGraph schema, this is a union of all indexed types.
386
+
387
+ Not intended for use by clients other than Apollo.
388
+ EOS
376
389
 
377
- t.subtypes(*entity_type_names)
390
+ t.subtypes(*entity_type_names)
391
+ end
378
392
  end
379
393
  end
380
394
 
@@ -382,15 +396,15 @@ module ElasticGraph
382
396
  register_graphql_extension GraphQL::EngineExtension, defined_at: require_path
383
397
 
384
398
  require(require_path = "elastic_graph/apollo/graphql/entities_field_resolver")
385
- register_graphql_resolver :apollo_entities, GraphQL::EntitiesFieldResolver, defined_at: require_path
399
+ register_graphql_resolver :apollo_entities, GraphQL::EntitiesFieldResolver, defined_at: require_path, built_in: true
386
400
 
387
401
  require(require_path = "elastic_graph/apollo/graphql/service_field_resolver")
388
- register_graphql_resolver :apollo_service, GraphQL::ServiceFieldResolver, defined_at: require_path
402
+ register_graphql_resolver :apollo_service, GraphQL::ServiceFieldResolver, defined_at: require_path, built_in: true
389
403
 
390
404
  require(require_path = "elastic_graph/apollo/graphql/apollo_entity_ref_resolver")
391
- register_graphql_resolver :apollo_entity_ref, GraphQL::ApolloEntityRefResolver::ForSingleId, defined_at: require_path
392
- register_graphql_resolver :apollo_entity_ref_list, GraphQL::ApolloEntityRefResolver::ForIdList, defined_at: require_path
393
- register_graphql_resolver :apollo_entity_ref_paginated, GraphQL::ApolloEntityRefResolver::ForPaginatedList, defined_at: require_path
405
+ register_graphql_resolver :apollo_entity_ref, GraphQL::ApolloEntityRefResolver::ForSingleId, defined_at: require_path, built_in: true
406
+ register_graphql_resolver :apollo_entity_ref_list, GraphQL::ApolloEntityRefResolver::ForIdList, defined_at: require_path, built_in: true
407
+ register_graphql_resolver :apollo_entity_ref_paginated, GraphQL::ApolloEntityRefResolver::ForPaginatedList, defined_at: require_path, built_in: true
394
408
  end
395
409
 
396
410
  def apollo_object_type(name, &block)
@@ -426,7 +440,7 @@ module ElasticGraph
426
440
 
427
441
  def validate_entity_types_can_all_be_resolved(entity_types)
428
442
  unresolvable_field_errors =
429
- entity_types.reject(&:indexed?).filter_map do |object_type|
443
+ entity_types.reject(&:root_document_type?).filter_map do |object_type|
430
444
  key_field_names = object_type.directives
431
445
  .select { |dir| dir.name == "key" }
432
446
  # https://rubular.com/r/JEuYKzqnyR712A
@@ -463,7 +477,7 @@ module ElasticGraph
463
477
  end
464
478
 
465
479
  private_class_method def self.customize_root_query_type(type)
466
- if type.schema_def_state.object_types_by_name.values.any?(&:indexed?)
480
+ if type.schema_def_state.object_types_by_name.values.any?(&:root_document_type?)
467
481
  type.field "_entities", "[_Entity]!", graphql_only: true do |f|
468
482
  f.documentation <<~EOS
469
483
  A field required by the [Apollo Federation subgraph
@@ -9,21 +9,27 @@
9
9
  module ElasticGraph
10
10
  module Apollo
11
11
  module SchemaDefinition
12
- # The Apollo `_Entity` type is a type union of _all_ entity subtypes in an ElasticGraph schema.
13
- # However, unlike a normal union type:
14
- #
15
- # - `_Entity` is never an indexed type, and should not be treated as one (even though its subtypes are all indexed, which would
16
- # usually cause it to be treated as indexed!).
17
- # - A merged set of `graphql_fields_by_name` cannot be safely computed. That method raises errors if a field with the same name
18
- # has conflicting definitions on different subtypes, but we must allow that on `_Entity` subtypes.
12
+ # The Apollo `_Entity` type is a union of all entity types in an ElasticGraph schema. These overrides
13
+ # prevent ElasticGraph from treating `_Entity` like a normal indexed union type, which would trigger
14
+ # unwanted derived schema generation and validation.
19
15
  #
20
16
  # @private
21
17
  module EntityTypeExtension
18
+ # A merged set of `graphql_fields_by_name` cannot be safely computed. That method raises errors if a field with
19
+ # the same name has conflicting definitions on different subtypes, but we must allow that on `_Entity` subtypes.
22
20
  def graphql_fields_by_name
23
21
  {}
24
22
  end
25
23
 
26
- def indexed?
24
+ # `_Entity` is never a root document type, and should not be treated as one (even though its subtypes are all
25
+ # root document types, which would usually cause it to be treated as a root document type!).
26
+ def root_document_type?
27
+ false
28
+ end
29
+
30
+ # `_Entity` is never directly queryable from the root `Query` type. It's queried via the apollo
31
+ # `_entities(representations: ...)` field instead.
32
+ def directly_queryable?
27
33
  false
28
34
  end
29
35
  end
@@ -66,17 +66,12 @@ module ElasticGraph
66
66
  end
67
67
  end
68
68
 
69
- # Here we override `object_type` in order to automatically add the apollo `@key` directive to indexed types.
70
69
  def new_object_type(name)
71
70
  super(name) do |raw_type|
72
71
  raw_type.extend ObjectTypeExtension
73
72
  type = raw_type # : ElasticGraph::SchemaDefinition::SchemaElements::ObjectType & ObjectTypeExtension
74
73
 
75
74
  yield type if block_given?
76
-
77
- if type.indexed? && type.graphql_fields_by_name.key?("id")
78
- type.apollo_key fields: "id"
79
- end
80
75
  end
81
76
  end
82
77
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticgraph-apollo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Myron Marston
@@ -17,42 +17,42 @@ dependencies:
17
17
  requirements:
18
18
  - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 1.1.0
20
+ version: 1.2.0
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
- version: 1.1.0
27
+ version: 1.2.0
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: elasticgraph-support
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - '='
33
33
  - !ruby/object:Gem::Version
34
- version: 1.1.0
34
+ version: 1.2.0
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - '='
40
40
  - !ruby/object:Gem::Version
41
- version: 1.1.0
41
+ version: 1.2.0
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: graphql
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: 2.5.18
48
+ version: 2.6.2
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: 2.5.18
55
+ version: 2.6.2
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: apollo-federation
58
58
  requirement: !ruby/object:Gem::Requirement
@@ -79,70 +79,70 @@ dependencies:
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 1.1.0
82
+ version: 1.2.0
83
83
  type: :development
84
84
  prerelease: false
85
85
  version_requirements: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: 1.1.0
89
+ version: 1.2.0
90
90
  - !ruby/object:Gem::Dependency
91
91
  name: elasticgraph-admin
92
92
  requirement: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 1.1.0
96
+ version: 1.2.0
97
97
  type: :development
98
98
  prerelease: false
99
99
  version_requirements: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - '='
102
102
  - !ruby/object:Gem::Version
103
- version: 1.1.0
103
+ version: 1.2.0
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: elasticgraph-elasticsearch
106
106
  requirement: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - '='
109
109
  - !ruby/object:Gem::Version
110
- version: 1.1.0
110
+ version: 1.2.0
111
111
  type: :development
112
112
  prerelease: false
113
113
  version_requirements: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: 1.1.0
117
+ version: 1.2.0
118
118
  - !ruby/object:Gem::Dependency
119
119
  name: elasticgraph-opensearch
120
120
  requirement: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - '='
123
123
  - !ruby/object:Gem::Version
124
- version: 1.1.0
124
+ version: 1.2.0
125
125
  type: :development
126
126
  prerelease: false
127
127
  version_requirements: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - '='
130
130
  - !ruby/object:Gem::Version
131
- version: 1.1.0
131
+ version: 1.2.0
132
132
  - !ruby/object:Gem::Dependency
133
133
  name: elasticgraph-indexer
134
134
  requirement: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - '='
137
137
  - !ruby/object:Gem::Version
138
- version: 1.1.0
138
+ version: 1.2.0
139
139
  type: :development
140
140
  prerelease: false
141
141
  version_requirements: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - '='
144
144
  - !ruby/object:Gem::Version
145
- version: 1.1.0
145
+ version: 1.2.0
146
146
  email:
147
147
  - myron@squareup.com
148
148
  executables: []
@@ -188,10 +188,10 @@ licenses:
188
188
  - MIT
189
189
  metadata:
190
190
  bug_tracker_uri: https://github.com/block/elasticgraph/issues
191
- changelog_uri: https://github.com/block/elasticgraph/releases/tag/v1.1.0
192
- documentation_uri: https://block.github.io/elasticgraph/api-docs/v1.1.0/
191
+ changelog_uri: https://github.com/block/elasticgraph/releases/tag/v1.2.0
192
+ documentation_uri: https://block.github.io/elasticgraph/api-docs/v1.2.0/
193
193
  homepage_uri: https://block.github.io/elasticgraph/
194
- source_code_uri: https://github.com/block/elasticgraph/tree/v1.1.0/elasticgraph-apollo
194
+ source_code_uri: https://github.com/block/elasticgraph/tree/v1.2.0/elasticgraph-apollo
195
195
  gem_category: extension
196
196
  rdoc_options: []
197
197
  require_paths:
@@ -210,7 +210,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
210
210
  - !ruby/object:Gem::Version
211
211
  version: '0'
212
212
  requirements: []
213
- rubygems_version: 4.0.3
213
+ rubygems_version: 4.0.6
214
214
  specification_version: 4
215
215
  summary: Transforms an ElasticGraph project into an Apollo subgraph.
216
216
  test_files: []