Resolver
Annotation to mark a class as a resolver implementation for a field in a GraphQL schema.
This is the Java equivalent of Kotlin's @Resolver annotation. Applied to concrete resolver classes that extend generated resolver base classes (marked with ResolverFor).
Resolvers define custom resolution logic for fields that require runtime computation, database lookups, or complex business logic, rather than simple property access.
Required Selection Sets
Resolvers can declare required fields from the parent object or query root using fragments:
Object Value Fragment
Specifies fields needed from the parent object:
objectValueFragment = """
fragment _ on User {
firstName
lastName
}
"""
)
public class UserDisplayNameResolver extends UserDisplayNameResolverBase {
public CompletableFuture<String> resolve(Context ctx) {
User user = ctx.getObjectValue();
return CompletableFuture.completedFuture(
user.getFirstName() + " " + user.getLastName()
);
}
}
Query Value Fragment
Specifies fields needed from the Query root:
queryValueFragment = """
fragment _ on Query {
currentUser {
id
}
}
"""
)
Shorthand Syntax
For single-field requirements, use shorthand:
= "displayName")
Batch Resolvers
For efficient processing of multiple field requests (preventing N+1 queries), implement
batchResolve instead of resolve:
= "fragment _ on Character { id }")
public class CharacterHomeworldResolver extends CharacterHomeworldResolverBase {
public CompletableFuture<Map<Context, Planet>> batchResolve(List<Context> contexts) {
List<String> characterIds = contexts.stream()
.map(ctx -> ctx.getObjectValue().getId())
.toList();
return planetService.fetchByCharacterIds(characterIds)
.thenApply(planets -> matchContextsToPlanets(contexts, planets));
}
}