Michael schoenmaekers
Michael schoenmaekers

Reputation: 31

How to translate GraphQL interfaces to the Java world with graphql-java-kickstart library using spring-boot

I'm quite new to GraphQL and I'm struggling with how to translate the concept of the GraphQL interface to proper java code that works with the graphql-java-kickstart library in Spring Boot. I've spent quite some time searching online for answers but could not find a proper working example. Here my simple case I try to figure out:

GraphQL schema

  interface Notification {
    id: ID!
    date: String
    isOpened: Boolean!
    title: String
    description: String
  }
  
  type InvitationNotification implements  Notification {
    id: ID!
    date: String
    isOpened: Boolean!
    title: String
    description: String
    sendBy: String
  }
  
  type Query {
    notification(id: ID!): Notification!
  }

My (bad) translation


// Query resolver
@Component
public class Query implements GraphQLQueryResolver {

    Notification notification(UUID id) {
        return new InvitationNotification(id,
                OffsetDateTime.now(),
                false,
                "Connection request from notary xyz",
                "Blabla",
                "Notary xyz"
                );
    }
}

// POJO abstract class, omitted getters
public abstract class Notification {

    private final UUID id;

    private final OffsetDateTime date;

    private  final boolean isOpened;

    private final String title;

    private final String description;

    public Notification(UUID id, OffsetDateTime date, boolean isOpened, String title, String description) {
        this.id = id;
        this.date = date;
        this.isOpened = isOpened;
        this.title = title;
        this.description = description;
    }

// POJO that extends
public class InvitationNotification extends Notification {

    private final String sendBy;

    public InvitationNotification(UUID id, OffsetDateTime date, boolean isOpened, String title, String description, String sendBy) {
        super(id, date, isOpened, title, description);
        this.sendBy = sendBy;
    }

    public String getSendBy() {
        return sendBy;
    }
}
 
// Spring config bean
@Configuration
public class GraphQLConfig {

    @Bean
    public SchemaParserDictionary schemaParserDictionary() {
        return new SchemaParserDictionary().add(InvitationNotification.class);
    }

}

With the above code, I can successfully execute the following query that only queries the common attributes

# Query
query aQuery {
  notification(id: "c782bbb2-7929-4694-9236-8108b49d5ba7") {
    id,
    title,
    description,
    isOpened,
  }
}
# Result
{
  "data": {
    "notification": {
      "id": "c782bbb2-7929-4694-9236-8108b49d5ba7",
      "title": "Connection request from notary xyz",
      "description": "Blabla",
      "isOpened": false
    }
  }
}

With the above code, I get an error when I request the additional attribute

# Query
query aQuery {
  notification(id: "c782bbb2-7929-4694-9236-8108b49d5ba7") {
    id,
    title,
    description,
    isOpened,
    sendBy
  }
}
# Result
{
  "errors": [
    {
      "message": "Validation error of type FieldUndefined: Field 'sendBy' in type 'Notification' is undefined @ 'notification/sendBy'",
      "locations": [
        {
          "line": 38,
          "column": 5
        }
      ],
      "extensions": {
        "classification": "ValidationError"
      }
    }
  ],
  "data": null
}

I'm guessing I have to somewhere hint the library what classes implement the interface, so it can do an Instance Of type of thing, but I have no clue where.

It would be really helpful if an example was added to https://github.com/graphql-java-kickstart/samples

Note that I also reached out on the discussion section of graphql-java-kickstart/samples

Upvotes: 3

Views: 639

Answers (0)

Related Questions