拥有GraphQL模式:
type TypeA {
id: ID,
name: String,
other: TypeC
}
type TypeB {
id: ID,
name: String,
other: TypeC
}
我应该如何独立于源对象类型实现TypeC布线?我知道我能做到:
RuntimeWiring.newRuntimeWiring()
.type(TypeRuntimeWiring.newTypeWiring("TypeA")
.dataFetcher("other", dataFetcher_typeC.get())
.type(TypeRuntimeWiring.newTypeWiring("TypeB")
.dataFetcher("other", dataFetcher_typeC.get())
.build()
但是数据提取器依赖于源对象类型:
DataFetcher<CompletableFuture<Collection<TypeC>>> get() {
return dataFetchingEnvironment -> {
<??> sourceObj = dataFetchingEnvironment.getSource();
return getObject(sourceObj.someProperty);
};
}
给定两个POJO(TypeA和TypeB(都有对TypeC的引用字段,如何通过给定的引用而不是源对象来解析TypeC字段?
我实际上已经找到了两种可能的问题解决方案:
- 定义新布线时,获取源对象并从中获取字段。使用参数调用dataFetcher方法,类似于常规的java方法:
- 在数据提取器内部,从DataFetcherEnvironment获取字段名称。使用反射从源对象获取场
示例#1:
RuntimeWiring.newRuntimeWiring()
.type(TypeRuntimeWiring.newTypeWiring("TypeA")
.dataFetcher("other", environment -> {
TypeA sourceObj = environment.getSource();
return dataFetcher_typeC.get(sourceObj.other)})
.type(TypeRuntimeWiring.newTypeWiring("TypeB")
TypeB sourceObj = environment.getSource();
return dataFetcher_typeC.get(sourceObj.other)})
.build()
示例2:
DataFetcher<CompletableFuture<Collection<TypeC>>> get() {
return dataFetchingEnvironment -> {
Field declaredField = dataFetchingEnvironment.getSource().getClass()
.getDeclaredField(dataFetchingEnvironment.getField().getName());
declaredField.setAccessible(true);
String value = (String) declaredField.get(dataFetchingEnvironment.getSource());
return getObject(sourceObj.someProperty);
};
}
第二种选择看起来更好,但仍然不确定这是否是正确的方法。
从这里的文档
dataFetchingEnvironment提供了getExecutionStepInfo((方法,该方法返回ExecutionStepInfo对象。从那里,您可以获得父级信息。
ExecutionStepInfo executionStepInfo = environment.getExecutionStepInfo();
ExecutionStepInfo parentInfo = executionStepInfo.getParent();
GraphQLObjectType parentType = (GraphQLObjectType) parentInfo.getUnwrappedNonNullType();
// parentType.getName() returns you "TypeA" or "TypeB"