问题描述
我希望使用另一种对象类型将字段值传递给已解析的字段.
I am looking to pass a field value to a resolved field using another object type.
如果我有客户 > 用户 > 个人资料",另一种表达方式 - 我如何将客户中的 CustomerID 字段值作为参数或变量传递给个人资料,以便正确解析?
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?
推荐答案
正好有 5 种可能性(从 graphql-java v12 开始)向任何级别的解析器(DataFetcher
)提供信息:
There's exactly 5 possibilities (as of graphql-java v12) to provide info to a resolver (DataFetcher
) at any level:
1) 直接在查询中传递它们(可能在多个级别):
{customer(id: 3) {
user {
profile(id: 3) {
name
}
}
}
}
2) 从 source 对象中获取值
2) Get values from the source object
source 是封闭查询的结果.在您的情况下,customer
查询的来源是根(无论您在查询执行时提供什么,例如
The source is the result of the enclosing query.In your case, the source for the customer
query is the root (whatever you provided at the query execution time, e.g.
graphQL.execute(ExecutionInput.newExecutionInput()
.query(query)
.root(root)
.build())
user
查询的来源是 customer
查询返回的任何内容,大概是一些 Customer
实例.profile
查询的来源是 user
查询返回的任何内容,大概是一个 User
实例.您可以通过 DataFetchingEnvironment#getSource()
获取源.因此,如果 User
包含您想要的 CustomerID
,只需通过 ((User) env.getSource()).getCustomerId()
获取它>.如果没有,请考虑将结果包装到一个对象中,该对象将包含您在子查询中需要的所有内容.
The source for the user
query is whatever customer
query returned, presumably some Customer
instance.
The source for the profile
query is whatever the user
query returned, presumably a User
instance.You can get a hold of the source via DataFetchingEnvironment#getSource()
. So, if User
contains the CustomerID
you're after, just get it via ((User) env.getSource()).getCustomerId()
. If not, consider wrapping the result into an object that would contain all you need in the sub-queries.
3) 使用共享上下文传递值
graphql-java 将为您提供一个 GraphQLContext
实例.因此,在 customer
的 DataFetcher
中,您可以将 CustomerID
存储到其中:
graphql-java will give you an instance of GraphQLContext
if you don't provide a custom context by yourself. So, inside the DataFetcher
for customer
, you can store the CustomerID
into it:
Customer customer = getCustomer();
GraphQLContext context = env.getContext();
context.put("CustomerID", customer.getId());
稍后,在 profile
的 DataFetcher
中,您可以从上下文中获取它:
Later on, inside the DataFetcher
for profile
, you can get it from the context:
GraphQLContext context = env.getContext();
context.get("CustomerID");
要提供自定义上下文,请在执行查询时传递它:
To provide a custom context, pass it when executing the query:
ExecutionInput input = ExecutionInput.newExecutionInput()
.query(operation)
.context(new ConcurrentHashMap<String, Object>())
.build()
graphQL.execute(query, input);
代替 ConcurrentHashMap
,您可以使用类型化对象,但您必须确保字段是 volatile
或 getter/setters 同步
或其他线程安全的.
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.
这种方式是有状态的,因此最难管理,所以只有在所有其他方法都失败时才使用它.
This way is stateful, thus the hardest to manage, so use it only if all else fails.
4) 直接获取传递给父字段的参数(可能从 graphql-java v11 开始)
ExecutionStepInfo stepInfo = dataFetchingEnvironment.getExecutionStepInfo();
stepInfo.getParent().getArguments(); // get the parent arguments
5) 使用 local 上下文传递值(可能从 graphql-java v12 开始)
5) Pass the values around using the local context (possible as of graphql-java v12)
不是直接返回结果,而是将其包装成一个DataFetcherResult
.这样,您还可以将任何对象附加为 localContext
,这些对象将通过 DataFetchingEnvironment#getLocalContext()
Instead of returning the result directly, wrap it into a DataFetcherResult
. That way you can also attach any object as a localContext
that will be available to all child DataFetcher
s via DataFetchingEnvironment#getLocalContext()
这篇关于Java GraphQL - 将字段值传递给对象的解析器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!