5

I know how to retrieve a bean from a service in a datafetcher:

public class MyDataFetcher implements DataFetcher {
  ...

  @Override
  public Object get(DataFetchingEnvironment environment) {
    return myService.getData();
  }
}

But schemas with nested lists should use a BatchedExecutionStrategy and create batched DataFetchers with get() methods annotated @Batched (see graphql-java doc).

But where do I put my getData() call then?

///// Where to put this code?
List list = myService.getData();
/////

public class MyDataFetcher implements DataFetcher {

  @Batched
  public Object get(DataFetchingEnvironment environment) {
    return list.get(environment.getIndex()); // where to get the index?
  }
}

1 Answer 1

5

WARNING: The original BatchedExecutionStrategy has been deprecated and will get removed. The current preferred solution is the Data Loader library. Also, the entire execution engine is getting replaced in the future, and the new one will again support batching "natively". You can already use the new engine and the new BatchedExecutionStrategy (both in nextgen packages) but they have limited support for instrumentations. The answer below applies equally to both the legacy and the nextgen execution engine.

Look at it like this. Normal DataFetcherss receive a single object as source (DataFetchingEnvironment#getSource) and return a single object as a result. For example, if you had a query like:

{
   user (name: "John") {
       company {
           revenue
       }
}

Your company resolver (fetcher) would get a User object as source, and would be expected to somehow return a Company based on that e.g.

User owner = (User) environment.getSource();
Company company = companyService.findByOwner(owner);
return company;

Now, in the exact same scenario, if your DataFetcher was batched, and you used BatchedExecutionStrategy, instead of receiving a User and returning a Company, you'd receive a List<User> and would return a List<Company> instead.

E.g.

List<User> owners = (List<User>) environment.getSource();
List<Company> companies = companyService.findByOwners(owners);
return companies;

Notice that this means your underlying logic must have a way to fetch multiple things at once, otherwise it wouldn't be batched. So your myService.getData call would need to change, unless it can already fetch data for multiple source object in one go.

Also notice that batched resolution makes sense in nested queries only, as the top level resolver can already fetch a list of object, without the need for batching.

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

Comments

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.