Skip to content

Prevent sending union type to wrong service, only query union subselection#231

Merged
JohnStarich merged 3 commits intomasterfrom
bugfix/union-inline-fragment-to-wrong-service
May 5, 2026
Merged

Prevent sending union type to wrong service, only query union subselection#231
JohnStarich merged 3 commits intomasterfrom
bugfix/union-inline-fragment-to-wrong-service

Conversation

@JohnStarich
Copy link
Copy Markdown
Member

@JohnStarich JohnStarich commented Apr 28, 2026

Follow-up to #230

  • Add failing test for sending union inline fragment to wrong service
  • Collapse union selection set into one flat set of fragment subselections.

We can make this assumption because the GraphQL spec requires union types be object types:

GraphQL Unions represent an object that could be one of a list of GraphQL Object types, but provides for no guaranteed fields between those types.
– https://spec.graphql.org/October2021/#sec-Unions

@JohnStarich JohnStarich force-pushed the bugfix/union-inline-fragment-to-wrong-service branch from 0cefb55 to de5ea17 Compare April 28, 2026 22:03
Comment thread plan_test.go
Comment on lines +1906 to +1919
for step := range allSteps(plans[0].RootStep) {
url := step.Queryer.(*graphql.SingleRequestQueryer).URL()
t.Logf("Found step on %q: %s", url, step.QueryString)
switch url {
case location0:
assert.NotContains(t, step.QueryString, "Foo", "Location 0 must not be called with 'Foo' union type")
assert.Equal(t, strings.TrimSpace(`
query($id: ID!) {
node(id: $id) {
... on Bar {
bar
}
}
}`), strings.TrimSpace(step.QueryString))
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently failing here with:

--- FAIL: TestPlanQuery_unionShouldNotBeQueriedOnOtherServices (0.00s)
    plan_test.go:1908: Found step on "": query {
                id
        }
    plan_test.go:1908: Found step on "url1": query {
                foo {
                        id
                }
        }
    plan_test.go:1908: Found step on "url0": query ($id: ID!) {
                node(id: $id) {
                        ... on Foo {
                                ... on Bar {
                                        bar
                                }
                        }
                }
        }
    plan_test.go:1911:
                Error Trace:    plan_test.go:1911
                Error:          "query ($id: ID!) {\n\tnode(id: $id) {\n\t\t... on Foo {\n\t\t\t... on Bar {\n\t\t\t\tbar\n\t\t\t}\n\t\t}\n\t}\n}\n" should not contain "Foo"
                Test:           TestPlanQuery_unionShouldNotBeQueriedOnOtherServices
                Messages:       Location 0 must not be called with 'Foo' union type
    plan_test.go:1912:
                Error Trace:    plan_test.go:1912
                Error:          Not equal:
                                expected: "query($id: ID!) {\n\tnode(id: $id) {\n\t\t... on Bar {\n\t\t\tbar\n\t\t}\n\t}\n}"
                                actual  : "query ($id: ID!) {\n\tnode(id: $id) {\n\t\t... on Foo {\n\t\t\t... on Bar {\n\t\t\t\tbar\n\t\t\t}\n\t\t}\n\t}\n}"

                                Diff:
                                --- Expected
                                +++ Actual
                                @@ -1,5 +1,7 @@
                                -query($id: ID!) {
                                +query ($id: ID!) {
                                        node(id: $id) {
                                -               ... on Bar {
                                -                       bar
                                +               ... on Foo {
                                +                       ... on Bar {
                                +                               bar
                                +                       }
                                                }

Collapse union selection set into one flat set of fragment subselections.
We can make this assumption because the GraphQL spec requires union types
be object types.
https://spec.graphql.org/October2021/#sec-Unions
@JohnStarich JohnStarich marked this pull request as ready for review May 5, 2026 21:00
@JohnStarich JohnStarich changed the title Prevent sending union type to wrong service Prevent sending union type to wrong service, only query union subselection May 5, 2026
@JohnStarich JohnStarich merged commit 0ce677b into master May 5, 2026
5 checks passed
@JohnStarich JohnStarich deleted the bugfix/union-inline-fragment-to-wrong-service branch May 5, 2026 21:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant