Skip to content
This repository was archived by the owner on Dec 19, 2023. It is now read-only.
This repository was archived by the owner on Dec 19, 2023. It is now read-only.

GraphQLAnnotationsAutoConfiguration should not include irrelevant types in the generated schema #502

Closed
@devopsix

Description

@devopsix

Is your feature request related to a problem? Please describe.

When using GraphQL-Java Annotations and when using Java interfaces and abstract classes for backing GraphQL interfaces then irrelevant types are added to the generated GraphQL schema.

Given the Character interface and the Human and Droid types as used throughout the Introduction to GraphQL:

interface Character {
  name: String
  friends: [Character]
}

type Human implements Character {
  name: String
  friends: [Character]
}

type Droid implements Character {
  name: String
  friends: [Character]
}

And given I want to use the same classes for both defining the GraphQL schema and as JPA entities.

Then my classes will look something like this:

@GraphQLTypeResolver(CharacterTypeResolver.class) // CharacterTypeResolver not shown
public interface Character {
  @GraphQLField
  String getName();
  @GraphQLField
  Set<Character> getFriends();
}

@Entity
@Table(name = "character")
public abstract class AbstractCharacter implements Character {
  private String name;
  @ManyToMany(targetEntity = AbstractCharacter.class)
  private Set<Character> friends;
  @GraphQLField
  public String getName() { return name; }
  public void setName(String name) { this.name = name; }
  @GraphQLField
  public Set<Character> getFriends() { return friends; }
  public void setFriends(Set<Character> friends) { this.friends = friends; }
}

@Entity
public class Human extends AbstractCharacter implements Character {
}

@Entity
public class Droid extends AbstractCharacter implements Character {
}

@GraphQLQueryResolver
public class Query {
    @GraphQLField
    public Character hero() { return null; }
    @GraphQLField
    public Human human() { return null; }
    @GraphQLField
    public Droid droid() { return null; }
}

Both AbstractCharacter implements Character and Droid/Human extends AbstractCharacter implements Character are required in order to satisfy the needs of GraphQL-Java Annotations and JPA.

The schema generated by GraphQL-Java Annotations's AnnotationsSchemaCreator will contain these types:

interface Character {
friends: [Character]
name: String
}

type Droid implements Character {
friends: [Character]
name: String
}

type Human implements Character {
friends: [Character]
name: String
}

type Query {
droid: Droid
hero: Character
human: Human
}

That's 100 % matching my expectations.

In contrast, the schema generated by GraphQLAnnotationsAutoConfiguration will contain these types:

interface Character {
friends: [Character]
name: String
}

type AbstractCharacter implements Character {
friends: [Character]
name: String
}

type Droid implements Character {
friends: [Character]
name: String
}

type Human implements Character {
friends: [Character]
name: String
}

type Query {
droid: Droid
hero: Character
human: Human
}

The AbstractCharacter type has no relevance to the GraphQL schema.

Describe the solution you'd like

I would like GraphQLAnnotationsAutoConfiguration to not add the AbstractCharacter type to the schema. Excluding all abstract classes would be an obvious approach which would work perfectly fine for my use case but which may constitute a breaking change for other users.

If inavoidable, I would be fine with having to mark that class for exclusion.

Additional context

Please find an example project with a Spring Boot test for reproducing the behavior described above in the attached
graphql-spring-boot-annotations.zip file.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions