Question: Edge types losing node fields after SDL round-trip - expected behavior or bug? #1075
Closed
marcdaniels-toast
started this conversation in
General
Replies: 2 comments 1 reply
|
Here's the diff that adds the three demonstration tests mentioned above: diff --git a/elasticgraph-schema_definition/spec/unit/elastic_graph/schema_definition/graphql_schema/interface_type_spec.rb b/elasticgraph-schema_definition/spec/unit/elastic_graph/schema_definition/graphql_schema/interface_type_spec.rb
index dea8b78d..e57e9af3 100644
--- a/elasticgraph-schema_definition/spec/unit/elastic_graph/schema_definition/graphql_schema/interface_type_spec.rb
+++ b/elasticgraph-schema_definition/spec/unit/elastic_graph/schema_definition/graphql_schema/interface_type_spec.rb
@@ -111,6 +111,115 @@ module ElasticGraph
include_examples "#implements",
graphql_definition_keyword: "interface",
ruby_definition_method: :interface_type
+
+ it "preserves all edge node fields when all children sort after parents (5-level hierarchy)" do
+ # 5-level hierarchy: Alpha < Bravo < Charlie < Delta < Echo
+ # All children > parent
+ intermediate_sdl = define_schema do |api|
+ api.interface_type "Alpha" do |t|
+ t.field "id", "ID!"
+ end
+
+ api.interface_type "Bravo" do |t|
+ t.implements "Alpha"
+ t.field "id", "ID!"
+ end
+
+ api.interface_type "Charlie" do |t|
+ t.implements "Bravo"
+ t.field "id", "ID!"
+ end
+
+ api.interface_type "Delta" do |t|
+ t.implements "Charlie"
+ t.field "id", "ID!"
+ end
+
+ api.object_type "Echo" do |t|
+ t.implements "Delta"
+ t.field "id", "ID!"
+ t.index "echos"
+ end
+ end
+
+ puts "\n=== Edge definitions BEFORE round-trip ==="
+ puts edge_type_from(intermediate_sdl, "Echo")
+ puts edge_type_from(intermediate_sdl, "Delta")
+ puts edge_type_from(intermediate_sdl, "Charlie")
+ puts edge_type_from(intermediate_sdl, "Bravo")
+ puts edge_type_from(intermediate_sdl, "Alpha")
+
+ round_tripped_sdl = ::GraphQL::Schema.from_definition(intermediate_sdl).to_definition
+
+ puts "\n=== Edge definitions AFTER round-trip ==="
+ puts edge_type_from(round_tripped_sdl, "Echo")
+ puts edge_type_from(round_tripped_sdl, "Delta")
+ puts edge_type_from(round_tripped_sdl, "Charlie")
+ puts edge_type_from(round_tripped_sdl, "Bravo")
+ puts edge_type_from(round_tripped_sdl, "Alpha")
+
+ # All edges should retain node fields
+ expect(edge_type_from(round_tripped_sdl, "Echo")).to include("node: Echo")
+ expect(edge_type_from(round_tripped_sdl, "Delta")).to include("node: Delta")
+ expect(edge_type_from(round_tripped_sdl, "Charlie")).to include("node: Charlie")
+ expect(edge_type_from(round_tripped_sdl, "Bravo")).to include("node: Bravo")
+ expect(edge_type_from(round_tripped_sdl, "Alpha")).to include("node: Alpha")
+ end
+
+ it "demonstrates bug: concrete type < parent causes grandparent to lose node (5-level hierarchy)" do
+ # Hierarchy: Alpha → Bravo → Echo → Delta → Charlie
+ # Charlie < Delta → Echo (grandparent) loses node
+ # node loss cascades upward
+ intermediate_sdl = define_schema do |api|
+ api.interface_type "Alpha" do |t|
+ t.field "id", "ID!"
+ end
+
+ api.interface_type "Bravo" do |t|
+ t.implements "Alpha"
+ t.field "id", "ID!"
+ end
+
+ api.interface_type "Echo" do |t|
+ t.implements "Bravo"
+ t.field "id", "ID!"
+ end
+
+ api.interface_type "Delta" do |t|
+ t.implements "Echo"
+ t.field "id", "ID!"
+ end
+
+ api.object_type "Charlie" do |t|
+ t.implements "Delta"
+ t.field "id", "ID!"
+ t.index "charlies"
+ end
+ end
+
+ puts "\n=== Edge definitions BEFORE round-trip ==="
+ puts edge_type_from(intermediate_sdl, "Charlie")
+ puts edge_type_from(intermediate_sdl, "Delta")
+ puts edge_type_from(intermediate_sdl, "Echo")
+ puts edge_type_from(intermediate_sdl, "Bravo")
+ puts edge_type_from(intermediate_sdl, "Alpha")
+
+ round_tripped_sdl = ::GraphQL::Schema.from_definition(intermediate_sdl).to_definition
+
+ puts "\n=== Edge definitions AFTER round-trip ==="
+ puts edge_type_from(round_tripped_sdl, "Charlie")
+ puts edge_type_from(round_tripped_sdl, "Delta")
+ puts edge_type_from(round_tripped_sdl, "Echo")
+ puts edge_type_from(round_tripped_sdl, "Bravo")
+ puts edge_type_from(round_tripped_sdl, "Alpha")
+
+ # All edges should retain node fields
+ expect(edge_type_from(round_tripped_sdl, "Charlie")).to include("node: Charlie")
+ expect(edge_type_from(round_tripped_sdl, "Delta")).to include("node: Delta")
+ expect(edge_type_from(round_tripped_sdl, "Echo")).to include("node: Echo") # This will fail (bug)
+ expect(edge_type_from(round_tripped_sdl, "Bravo")).to include("node: Bravo") # This will fail (bug)
+ expect(edge_type_from(round_tripped_sdl, "Alpha")).to include("node: Alpha") # This will fail (bug)
+ end
end
end
end |
0 replies
|
Thanks for reporting this! It's a graphql-ruby bug. I've reported it there: In the meantime, there's a workaround--we can list all the interface ancestors in the Want to take a stab at implementing that? While I'm calling it a workaround, we're arguably not in compliance with the GraphQL spec and we should be so it's a good thing to improve, regardless. |
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Context
I'm working on #1029 in steps and I'm enhancing the widgets.rb schema with an example multi-level interface hierarchy to show index inheritance. While testing this kind of configuration, I came across an issue related to how we round-trip the SDL through
::GraphQL::Schema.from_definition().to_definition()in SchemaArtifactManager. For my multi-level interface hierarchy, some interface Edge types are losing their node fields during this from-to "round-trip". I'm still new to this codebase and GraphQL in general and trying to understand if this can be explained as expected behavior or if it's a bug in the GraphQL gem.What I'm Seeing
I've isolated this to seemingly relate to the alphabetical ordering of the type names in the hierarchy. In interface hierarchies of 4+ levels, when a child type's name sorts alphabetically before its parent interface name, the grandparent interface's Edge loses its node field after the round-trip. This seems to cascade up the hierarchy.
Example:
Why I'm Confused
Test Cases
I've written three minimal test cases using NATO phonetic alphabet names to make the alphabetical relationships clear:
I'll post the diff that adds these three tests so you can run these locally and see the issue or adjust the hierarchy/debug messages, etc.
I'm looking for advice on how to proceed. I could ignore this issue and just set up an example hierarchy less than 4 levels deep, but it seems more like a bug in
::GraphQL::Schema?All reactions