我希望使用另一个对象类型将字段值传递给已解析的字段。
如果我有“客户>用户>配置文件”的另一种方式 - 我怎样才能将Customer中的CustomerID字段值作为参数或变量传递给Profile,以便正确解析?
有四种可能性(如graphql-java v11,第5版将在graphql-java v12中提供),以便在任何级别向解析器(DataFetcher
)提供信息:
1)在查询中直接传递它们(可能在多个级别上):
{customer(id: 3) {
user {
profile(id: 3) {
name
}
}
}
}
2)从源对象获取值
源是封闭查询的结果。在您的情况下,customer
查询的源是根上下文(无论您在查询执行时提供什么,例如graphQL.execute(query, rootContext)
)。
user
查询的来源是返回的customer
查询,可能是一些Customer
实例。
profile
查询的来源是user
查询返回的任何内容,可能是User
实例。您可以通过DataFetchingEnvironment#getSource()
获取源代码。所以,如果User
包含你所追求的CustomerID
,那么只需通过((User) env.getSource()).getCustomerId()
获取它。如果没有,请考虑将结果包装到一个对象中,该对象将包含子查询中所需的所有内容。
3)使用共享上下文传递值
例如,您可以使用ConcurrentHashMap
作为上下文:
ExecutionInput input = ExecutionInput.newExecutionInput()
.query(operation)
.context(new ConcurrentHashMap<String, Object>())
.build()
graphQL.execute(query, input);
然后,在DataFetcher
的customer
内,你将CustomerID
存入其中:
Customer customer = getCustomer();
Map<String, Object> context = env.getContext();
context.put("CustomerID", customer.getId());
稍后,在DataFetcher
的profile
内,你可以从上下文中得到它:
Map<String, Object> context = env.getContext();
context.get("CustomerID");
您可以使用类型化对象而不是ConcurrentHashMap
,但您必须确保字段为volatile
或getters / setters synchronized
或其他线程安全。
这种方式是有状态的,因此最难管理,因此只有在所有其他方法都失败时才使用它。
4)直接获取传递给父字段的参数(从graphql-java v11开始)
ExecutionStepInfo stepInfo = dataFetchingEnvironment.getExecutionStepInfo();
stepInfo.getParent().getArguments(); // get the parent arguments
5)使用本地上下文传递值(从graphql-java v12开始)
而不是直接返回结果,将其包装成DataFetcherResult
。这样你也可以附加任何对象作为localContext
,将通过DataFetcher
可供所有儿童DataFetchingEnvironment#getLocalContext()
s使用