Skip to content

Union type in an interface-only cannot be used #597

Open
@svilen-ivanov-kubit

Description

@svilen-ivanov-kubit

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions