Java GraphQL - Pass field values to resolver for objects

廉价感情. 提交于 2020-01-23 15:35:32

问题


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



来源:https://stackoverflow.com/questions/44159753/java-graphql-pass-field-values-to-resolver-for-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!