GraphQL Java: Using @Batched DataFetcher

倖福魔咒の 提交于 2020-05-15 03:58:08

问题


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:


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.



来源:https://stackoverflow.com/questions/42041371/graphql-java-using-batched-datafetcher

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