Home
New @GraphQLIgnore Annotation: Code-First Schema in Spring
I recently incorporated the spring-graphql library into a project that had been using the graphql-java-annotations library for satisfying the “code-first” approach to GraphQL schema generation.
The problem I faced: how to unify the interfaces defining the schema, with the controllers defining the actual data fetchers executed at runtime?
As an example, a method used to generate the schema using graphql-java-annotations might be:
public interface Foo {
@GraphQLField
@GraphQLNonNull Bar bar(@GraphQLName("baz") @GraphQLNonNull String baz);
}
while the method mapped to that field at runtime using spring-graphql might be:
public class FooController {
@SchemaMapping
public Bar bar(
Foo foo,
GraphQLContext context,
@Argument String baz) {
// ...
}
}
The schema I was working with was non-trivial, so I ruled out keeping these definitions separate, as it would have quickly become chaotic.
So I experimented with various approaches to making the controllers implement the original interfaces, but ultimately abandoned that approach after realizing it wasn’t possible.
Eventually I merged the interface definitions into the controllers, producing methods like this:
public class FooController {
@SchemaMapping
@GraphQLField
public @GraphQLNonNull Bar bar(
Foo foo,
GraphQLContext context,
@Argument @GraphQLName("baz") @GraphQLNonNull String baz) {
// ...
}
}
New problem: what to do about parameters foo and context?
foois the “source” object on which this controller is operatingcontextis the extra state we have for this particular GraphQL request
If we run graphql-java over this method definition and ask it to produce a schema:
foois a valid schema type, but by including it, any caller of this field will be contractually required to provide aFoo; this is undesirable, as aFooneed only be supplied at runtime by the environmentcontextis not a valid schema type, sographql-javawill abort with an error
Prior to December 2023, there was no way to simply ignore these parameters at schema-generation time. In PR #299 of the graphql-java-annotations library, I added a new annotation @GraphQLIgnore that does just that: ignores any parameter on which it is present. Now we can write:
public class FooController {
@SchemaMapping
@GraphQLField
public @GraphQLNonNull Bar bar(
@GraphQLIgnore Foo foo,
@GraphQLIgnore GraphQLContext context,
@Argument @GraphQLName("baz") @GraphQLNonNull String baz) {
// ...
}
}
The end result is that this single method definition can be used both at compile-time for schema generation and at runtime for execution, without any duplication or extra maintenance burden. This should make the code-first GraphQL development style much more pleasant when using Spring’s GraphQL runtime library.