Interfaces and Unions
无论何时在 schema 中使用 interface 类型或 union 类型,都必须注册类型解析器。Interface 类型 和 Union 类型在 GraphQL documentation 中有说明。
例如,下面的 schema 定义了一个 Movie 接口类型,它具有两个不同的具体对象类型实现。
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
}
注册以下 datafetcher 以返回一个 movie 列表。datafetcher 返回了一个 Movie 类型的组合。
@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)
);
}
}
GraphQL 运行时需要知道 ActionMovie
的Java实例表示 ActionMovie
的 GraphQL 类型。这种映射是 TypeResolver
的职责。
小技巧:如果一个 Java 类型的名字与 GraphQL 中的类型名字定义一样,那么 DGS 框架将会自动创建一个
TypeResolver
。并不需要添加任何代码。
注册一个 Type Resolver
如果 Java 中类型的名称和 GraphQL 类型名称不一样,你需要提供一个 TypeResolver
。一个 Type resolver 可以帮助框架从具体的 Java 类型映射到 schema 中的正确对象类型。
使用 @DgsTypeResolver
注解去注册一个 type resolver。这个注解有一个 name
属性;将其设置为 [GraphQL] schema 中的 interface 类型或 union 类型的名称。resolver 接受一个 Java interface 类型的对象,并返回一个 String,该 String 是 schema 中定义的实例的具体对象类型。下面是一个针对 Movie
接口类型的 type resolver:
@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");
}
}
你可以添加 @DgsTypeResolver
给任何一个 @DgsComponent
类型。这意味着您可以将 type resolver 与负责返回此类型数据的 datafetcher 保持在同一个类中,或者您可以为它创建一个单独的类。
最后更新于
这有帮助吗?