GraphQL Java:使用@Batched DataFetcher

Mat*_*s M 4 graphql graphql-java

我知道如何从 datafetcher 中的服务中检索 bean

public class MyDataFetcher implements DataFetcher {
  ...

  @Override
  public Object get(DataFetchingEnvironment environment) {
    return myService.getData();
  }
}
Run Code Online (Sandbox Code Playgroud)

但是具有嵌套列表的模式应该使用 BatchedExecutionStrategy 并使用 @Batched 注释的 get() 方法创建批处理 DataFetcher(请参阅 graphql-java 文档)。

但是我把我的 getData() 调用放在哪里呢?

///// 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?
  }
}
Run Code Online (Sandbox Code Playgroud)

kaq*_*qao 5

警告:原件BatchedExecutionStrategy已被弃用,将被删除。当前首选的解决方案是Data Loader 库。此外,整个执行引擎在未来将被替换,新引擎将再次“本地”支持批处理。你已经可以使用新的引擎新的BatchedExecutionStrategy(无论是在nextgen包),但他们有控制仪表有限的支持。下面的答案同样适用于旧版和下一代执行引擎。

像这样看。Normal DataFetcherss 接收单个对象作为源 ( DataFetchingEnvironment#getSource) 并返回单个对象作为结果。例如,如果您有如下查询:

{
   user (name: "John") {
       company {
           revenue
       }
}
Run Code Online (Sandbox Code Playgroud)

你的company解析器(fetcher)会得到一个User对象作为源,并且期望以某种方式返回一个Company基于例如

User owner = (User) environment.getSource();
Company company = companyService.findByOwner(owner);
return company;
Run Code Online (Sandbox Code Playgroud)

现在,在完全相同的场景中,如果您DataFetcher被批处理,并且您使用BatchedExecutionStrategy,而不是接收 aUser并返回 a Company,您将收到 aList<User>并返回 a List<Company>

例如

List<User> owners = (List<User>) environment.getSource();
List<Company> companies = companyService.findByOwners(owners);
return companies;
Run Code Online (Sandbox Code Playgroud)

请注意,这意味着您的底层逻辑必须有一种方法可以一次获取多个内容,否则它不会被批处理。所以你的myService.getData调用需要改变,除非它已经可以一次性获取多个源对象的数据。

另请注意,批处理解析仅在嵌套查询中有意义,因为顶级解析器已经可以获取对象列表,而无需批处理。