[英]Java GraphQL - Pass field values to resolver for objects
I am looking to pass a field value to a resolved field using another object type. 我正在寻找使用其他对象类型将字段值传递给已解析的字段。
Another way to put it if I have `Customer > User > Profile' - how can I pass the CustomerID field value that would be in customer to Profile as an argument or variable in order to resolve correctly? 如果我有“客户>用户>个人资料”,则可以用另一种方式输入-如何将客户中的CustomerID字段值作为参数或变量传递给个人资料,以便正确解析?
There's exactly 5 possibilities (as of graphql-java v12) to provide info to a resolver ( DataFetcher
) at any level: 完全有5种可能性(从graphql-java v12开始)可以在任何级别向解析器(
DataFetcher
)提供信息:
1) Directly pass them in the query (possibly on multiple levels): 1)直接在查询中传递它们(可能在多个级别上):
{customer(id: 3) {
user {
profile(id: 3) {
name
}
}
}
}
2) Get values from the source object 2)从源对象获取值
The source is the result of the enclosing query. 源是封闭查询的结果。 In your case, the source for the
customer
query is the root context (whatever you provided at the query execution time, eg graphQL.execute(query, rootContext)
). 在您的情况下,
customer
查询的源是根上下文(无论您在查询执行时提供了什么,例如graphQL.execute(query, rootContext)
)。
The source for the user
query is whatever customer
query returned, presumably some Customer
instance. user
查询的源是返回的任何customer
查询,大概是某些Customer
实例。
The source for the profile
query is whatever the user
query returned, presumably a User
instance. profile
查询的源是user
查询返回的任何内容,大概是User
实例。 You can get a hold of the source via DataFetchingEnvironment#getSource()
. 您可以通过
DataFetchingEnvironment#getSource()
保留源。 So, if User
contains the CustomerID
you're after, just get it via ((User) env.getSource()).getCustomerId()
. 因此,如果
User
包含您要User
的CustomerID
,只需通过((User) env.getSource()).getCustomerId()
即可获取它。 If not, consider wrapping the result into an object that would contain all you need in the sub-queries. 如果不是,请考虑将结果包装到一个包含子查询中所需全部内容的对象中。
3) Pass the values around using the shared context 3)使用共享上下文传递值
You can for example use a ConcurrentHashMap
as the context: 例如,您可以使用
ConcurrentHashMap
作为上下文:
ExecutionInput input = ExecutionInput.newExecutionInput()
.query(operation)
.context(new ConcurrentHashMap<String, Object>())
.build()
graphQL.execute(query, input);
Then, inside the DataFetcher
for customer
, you store the CustomerID
into it: 然后,里面
DataFetcher
的customer
,您的存储CustomerID
到它:
Customer customer = getCustomer();
Map<String, Object> context = env.getContext();
context.put("CustomerID", customer.getId());
Later on, inside the DataFetcher
for profile
, you can get it from the context: 稍后,在
profile
的DataFetcher
内部,您可以从上下文中获取它:
Map<String, Object> context = env.getContext();
context.get("CustomerID");
Instead of a ConcurrentHashMap
, you could be using a typed object, but you'd have to make sure the fields are volatile
or getters/setters synchronized
or otherwise thread-safe. 除了使用
ConcurrentHashMap
,您还可以使用类型化的对象,但是必须确保字段是volatile
或者是getter / setter synchronized
或者是线程安全的。
This way is stateful, thus the hardest to manage, so use it only if all else fails. 这种方式是有状态的,因此是最难管理的,因此仅在所有其他方式均失败时才使用它。
4) Directly get the arguments passed to a parent field (possible as of graphql-java v11) 4)直接获取传递给父字段的参数(自graphql-java v11起可能)
ExecutionStepInfo stepInfo = dataFetchingEnvironment.getExecutionStepInfo();
stepInfo.getParent().getArguments(); // get the parent arguments
5) Pass the values around using the local context (possible as of graphql-java v12) 5)使用本地上下文传递值(自graphql-java v12起可能)
Instead of returning the result directly, wrap it into a DataFetcherResult
. 而不是直接返回结果,而是将其包装到
DataFetcherResult
。 That way you can also attach any object as a localContext
that will be available to all child DataFetcher
s via DataFetchingEnvironment#getLocalContext()
这样,您还可以通过
DataFetchingEnvironment#getLocalContext()
将任何对象作为localContext
附加到所有子DataFetcher
可用的DataFetcher
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.