Description
I'm unable to use an union in an interface unless that union is referenced in a concrete type.
Here is an example:
type Query {
query: TestInterface
# dummy: DummyType
}
interface TestInterface {
testUnion: TestUnion
}
type TestInterfaceImpl implements TestInterface {
testUnion: TestUnion1
c: String
}
type DummyType {
testUnion: TestUnion
}
type TestUnion1 {
a: String
}
type TestUnion2 {
b: String
}
union TestUnion = TestUnion1 | TestUnion2
TestInterface
defines the testUnion
field to be TestUnion
. TestInterfaceImpl
narrows down the field testUnion
to TestUnion1
.
Expected behavior
The schema should be parsed properly
Actual behavior
I get the following error:
Exception in thread "main" graphql.kickstart.tools.SchemaError: Expected type 'TestUnion' to be a GraphQLOutputType, but it wasn't! Was a type only permitted for object types incorrectly used as an input type, or vice-versa?
at graphql.kickstart.tools.SchemaParser.determineType(SchemaParser.kt:385)
at graphql.kickstart.tools.SchemaParser.determineOutputType(SchemaParser.kt:368)
at graphql.kickstart.tools.SchemaParser.createField(SchemaParser.kt:283)
at graphql.kickstart.tools.SchemaParser.createInterfaceObject$lambda-32$lambda-31(SchemaParser.kt:233)
at graphql.schema.GraphQLInterfaceType$Builder.field(GraphQLInterfaceType.java:318)
at graphql.kickstart.tools.SchemaParser.createInterfaceObject(SchemaParser.kt:233)
at graphql.kickstart.tools.SchemaParser.parseSchemaObjects(SchemaParser.kt:82)
at graphql.kickstart.tools.SchemaParser.makeExecutableSchema(SchemaParser.kt:112)
at Main.main(Main.kt:39)
The library reports that TestUnion
is unused.
18:35:14.201 [main] WARN g.kickstart.tools.SchemaClassScanner - Schema type was defined but can never be accessed, and can be safely deleted: DummyType
18:35:14.201 [main] WARN g.kickstart.tools.SchemaClassScanner - Schema type was defined but can never be accessed, and can be safely deleted: TestUnion2
18:35:14.201 [main] WARN g.kickstart.tools.SchemaClassScanner - Schema type was defined but can never be accessed, and can be safely deleted: TestUnion
If I simply reference the TestUnion
in another query (uncomment line 3, dummy
), the schema is parsed successfully.
Steps to reproduce the bug
Here minimal reproducible repository: https://github.com/svilen-ivanov-kubit/gql-union. Simply run ./gradlew run
Notes
I'm migrating my code from version 5 to version 12 and I used to define TestUnion
to be an empty interface. This used pass with version 5 of the library but now it doesn't. It is invalid GraphQL according to the spec. Union type seems best according to the "Learn" section of the GQL site:
Union types are very similar to interfaces, but they don't get to specify any common fields between the types.
I was able to trace the issue to this change (fd28dbc, PR #83)
However, since my union is never a leaf (it is only referenced in interface) it is reported as unused and I get the error.
Let me know if the behaviour I'm expecting is correct.