graphql-java-kickstart / graphql-java-tools

A schema-first tool for graphql-java inspired by graphql-tools for JS
https://www.graphql-java-kickstart.com/tools/
MIT License
810 stars 174 forks source link

Interfaces and unions not allowed as types in a union #456

Open rideliner opened 3 years ago

rideliner commented 3 years ago

Description

A union can only contain object types. The class scanner fails to deeply scan a union if it contains another union or interface type.

Expected behavior

A union that contains another union or an interface should be valid.

type Query {
    entity: StarWarsEntity
}

interface Character {
    name: String
}

type Human implements Character {
    name: String
}

type Droid implements Character {
    name: String
}

type Planet {
    location: String
}

union StarWarsEntity = Character | Planet

Actual behavior

The SchemaClassScanner only looks at ObjectTypeDefinitions when a union is scanned. InterfaceTypeDefinitions and UnionTypeDefinitions are ignored.

graphql.kickstart.tools.SchemaClassScannerError: No object type found with name 'Character' for union: UnionTypeDefinition{name='StarWarsEntity'directives=[], memberTypes=[TypeName{name='Character'}, TypeName{name='Planet'}]}

Steps to reproduce the bug

interface StarWarsEntity {}
interface Character extends StarWarsEntity {
    String getName();
}

class Human implements Character {
    @Override
    String getName() {
        return null;
    }
}

class Droid implements Character {
    @Override
    String getName() {
        return null;
    }
}

class Planet implements StarWarsEntity {
    String location;
}
SchemaParser.newParser()
    .schemaString("...")
    .resolvers(new GraphQLQueryResolver() {
        StarWarsEntity getEntity() { return null; }
    })
    .dictionary(Human.class, Droid.class, Planet.class, Character.class)
    .scan();
jxnu-liguobin commented 3 years ago

Schema does not conform to the grapql specification

https://graphql.org/learn/schema/#union-types

lqc commented 3 years ago

As mentioned above this issue should be closed because according to spec, unions can only contain types - not other unions or interfaces: http://spec.graphql.org/draft/#sel-HAHdfFDABgCBlE9-X