问题
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?
回答1:
There's exactly 5 possibilities (as of graphql-java v12) to provide info to a resolver (DataFetcher
) at any level:
1) Directly pass them in the query (possibly on multiple levels):
{customer(id: 3) {
user {
profile(id: 3) {
name
}
}
}
}
2) Get values from the source object
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, e.g. graphQL.execute(query, rootContext)
).
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) Pass the values around using the shared context
You can for example use a ConcurrentHashMap
as the context:
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:
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:
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.
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)
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)
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()
来源:https://stackoverflow.com/questions/44159753/java-graphql-pass-field-values-to-resolver-for-objects