6

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 is no code, or other information about what you're using. I haven't used any GraphQL library for Java so YMMV but normally you'd attach this information to the values you return for each resolution point. When you get a User from a Customer it should carry some (or all) data from the Customer and likewise to Profile, so (naively) you'd probably do something ((Profile)resolveParams.getSource()).getUser().getCustomer().getId() Commented May 24, 2017 at 18:52

1 Answer 1

23

There are 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 (whatever you provided at the query execution time, e.g.

graphQL.execute(ExecutionInput.newExecutionInput()
    .query(query)
    .root(root)
    .build())

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

graphql-java passes around an instance of GraphQLContext available to all resolvers. 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());

Later on, inside the DataFetcher for profile, you can get it from the context:

String customerId = env.getContext().get("CustomerID");

To initialize a context, pass it when executing the query:

ExecutionInput input = ExecutionInput.newExecutionInput()
  .query(operation)
  .graphQLContext(new HashMap<>())
  .build()
graphQL.execute(query, input);

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

ExecutionStepInfo stepInfo = dataFetchingEnvironment.getExecutionStepInfo();
stepInfo.getParent().getArguments(); // get the parent arguments

5) Pass the values around using the local context

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 DataFetchers via DataFetchingEnvironment#getLocalContext()

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you very much! Could you please add the information about some use cases for using one or another way? And which way is more preferable among all of them?
@Max If you can naturally express the value as a property of the parent, #2 is the easiest. If not, and the value is simple (no deserialization needed), #4 is good. Barring those, #5 is good. #1 and #3 are less preferable.
@kaqqao regarding #4, how do I add arguments in the first place? it seems arguments is ImmutableMap.
@GovindaSakhare You don't. The code I showed is for looking up arguments passed by the client to a field above the current field. As the question required.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.