Error: "cannot query field "id" on type "UnionType"
prokaktus opened this issue · 3 comments
Hello!
I've met the error when using inline fragments.
Description
Schema:
type Cat {
id: ID!
name: String!
}
type Dog {
id: ID!
name: String!
}
union Animal = Cat | Dog
type Query {
animals: [Animal!]!
}
Query:
query MyQuery {
animals {
... on Cat {
id
name
}
... on Dog {
id
name
}
}
}
If Dog
and Cat
are defined in the same location, it works well.
But if you define Dog
and Cat
in different locations, then first query in plans generate:
(query generated by Gateway)
{
animals {
... on Cat {
id
name
}
id
}
}
Which is invalid, because we cannot query fields on Union
, except __typename
. Graphql spec told so:
the following query is invalid, because the union itself defines no fields:
{
firstSearchResult {
name
height
}
}
https://spec.graphql.org/June2018/#sec-Unions
Possible workaround
Use defined fragments.
Query like this will work:
query MyQuery {
animals {
... on Cat {
...CatFragment
}
... on Dog {
...DogFragment
}
}
}
fragment CatFragment on Cat {
id,
name
}
fragment DogFragment on Dog {
id,
name
}
I'll try to provide testcase and fix for this issue.
The same problem happens with query, if Dog
and Cat
from different locations:
query {
animals {
...CatFragment
...DogFragment
}
}
fragment CatFragment on Cat {
id
name
}
fragment DogFragment on Dog {
id
name
}
Turned out this is a lot trickier to fix than I expected.
Problem is somewhere there:
Lines 389 to 392 in 1078926
When gateway handling unions fragments, there added id
field to unions SelectionSet
, and this is invalid syntax for graphql.
Oh, damn yea this is going to bring you very deep into the weeds of the query planning process. It sounds like you are on the right track tho! Since its safe to assume that every boundary type has ID, you should be able to just ensure that ID shows up the different conditions for the union and instead of adding it straight to the selection set.