Skip to content

Latest commit

 

History

History

graphql-apt

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

Feign GraphQL APT

Annotation processor for feign-graphql that generates Java records from GraphQL schemas at compile time.

Given a @GraphqlSchema-annotated interface, this processor:

  • Parses the referenced .graphql schema file
  • Validates all @GraphqlQuery strings against the schema
  • Generates Java records for result types, input types, and enums
  • Maps custom scalars to Java types via @Scalar annotations

See the feign-graphql README for usage examples.

Generated Output

Result types with inner records

Nested result types are generated as inner records scoped to each query result. This ensures each query gets exactly the fields it selects, even when different queries target the same GraphQL type.

For a query like:

{
  starship(id: "1") {
    id name
    location { planet sector }
    specs { lengthMeters classification }
  }
}

The processor generates a single file with inner records:

public record StarshipResult(String id, String name, Location location, Specs specs) {

  public record Location(String planet, String sector) {}

  public record Specs(Integer lengthMeters, String classification) {}

}

Two different queries can select different fields from the same GraphQL type without conflict:

// Query 1: selects location { planet }
public record CharByPlanet(String id, Location location) {
  public record Location(String planet) {}
}

// Query 2: selects location { sector region }
public record CharByRegion(String id, Location location) {
  public record Location(String sector, String region) {}
}

Multiple root fields

An operation selecting several root fields gets a record with one component per field, mirroring the operation's own selection set rather than a single field's type:

query authorPage($authorId: ID!) {
  books(authorId: $authorId) { id title }
  reviews(authorId: $authorId) { id rating }
}
public record AuthorPage(Optional<List<Books>> books, Optional<List<Reviews>> reviews) {

  public record Books(String id, String title) {}

  public record Reviews(String id, Integer rating) {}

}

With a single root field the record still mirrors that field's type, so { character(id: "1") { id name } } keeps generating record CharacterResult(String id, String name).

Conflicting return type error

If two queries use the same return type name but select different fields, the processor reports compilation errors on both methods showing which fields each selects:

error: Conflicting return type 'CharResult': method selects [id, email] but method 'query1()' already selects [id, name]
  CharResult query2();
             ^
error: Conflicting return type 'CharResult': method selects [id, name] but method 'query2()' selects [id, email]
  CharResult query1();
             ^

Input types and enums

Input types and enums are generated as top-level files since they represent the full schema type:

public record CreateCharacterInput(String name, String email, Episode appearsIn) {}
public enum Episode {
  NEWHOPE,
  EMPIRE,
  JEDI
}

Deprecated schema elements

Set generateDeprecated = false on @GraphqlSchema, or generateDeprecated = Toggle.FALSE on a single @GraphqlQuery, to hide @deprecated schema elements. Generated types leave out deprecated fields, input fields and enum values. A query that uses a deprecated field, argument, input field or enum value fails to compile:

GraphQL validation error at line 1, column 22: Field 'email' is deprecated (use emails instead) and generateDeprecated is false

Maven Configuration

Add as a provided dependency so it runs during compilation but is not included at runtime:

<dependency>
  <groupId>io.github.openfeign.experimental</groupId>
  <artifactId>feign-graphql-apt</artifactId>
  <version>${feign.version}</version>
  <scope>provided</scope>
</dependency>