Interfaces and Unions
You must register type resolvers whenever you use interface types or union types in your schema. Interface types and union types are explained in the GraphQL documentation.
As an example, the following schema defines a Movie
interface type with two different concrete object type implementations.
type Query {
movies: [Movie]
}
interface Movie {
title: String
}
type ScaryMovie implements Movie {
title: String
gory: Boolean
scareFactor: Int
}
type ActionMovie implements Movie {
title: String
nrOfExplosions: Int
}
The following data fetcher is registered to return a list of movies.
The data fetcher returns a combination Movie
types.
@DgsComponent
public class MovieDataFetcher {
@DgsData(parentType = "Query", field = "movies")
public List<Movie> movies() {
return Lists.newArrayList(
new ActionMovie("Crouching Tiger", 0),
new ActionMovie("Black hawk down", 10),
new ScaryMovie("American Horror Story", true, 10),
new ScaryMovie("Love Death + Robots", false, 4)
);
}
}
The GraphQL runtime needs to know that a Java instance of ActionMovie
represents the ActionMovie
GraphQL type.
This mapping is the responsibility of a TypeResolver
.
Registering a Type Resolver¶
If the name of your Java type and GraphQL type don't match, you need to provide a TypeResolver
.
A type resolver helps the framework map from concrete Java types to the correct object type in the schema.
Use the @DgsTypeResolver
annotation to register a type resolver.
The annotation has a name
property; set this to the name of the interface type or union type in the [GraphQL] schema.
The resolver takes an object of the Java interface type, and returns a String which is the concrete object type of the instance as defined in the schema.
The following is a type resolver for the Movie
interface type introduced above:
@DgsTypeResolver(name = "Movie")
public String resolveMovie(Movie movie) {
if(movie instanceof ScaryMovie) {
return "ScaryMovie";
} else if(movie instanceof ActionMovie) {
return "ActionMovie";
} else {
throw new RuntimeException("Invalid type: " + movie.getClass().getName() + " found in MovieTypeResolver");
}
}
You can add the @DgsTypeResolver
annotation to any @DgsComponent
class.
This means you can either keep the type resolver in the same class as the data fetcher responsible for returning the data for this type, or you can create a separate class for it.