4

我希望使用另一种对象类型将字段值传递给已解析的字段。

如果我有“客户 > 用户 > 个人资料”,另一种说法是 - 如何将客户中的客户 ID 字段值作为参数或变量传递给个人资料以便正确解析?

4

1 回答 1

20

恰好有 5 种可能性(从 graphql-java v12 开始)向DataFetcher任何级别的解析器 ( ) 提供信息:

1)直接在查询中传递它们(可能在多个级别上):

{customer(id: 3) {
      user {
         profile(id: 3) {
             name
         }
      }
   }
}

2) 从对象中获取值

是封闭查询的结果。在您的情况下,customer查询的来源是根(无论您在查询执行时提供什么,例如

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

查询的来源user是返回的任何customer查询,可能是某个Customer实例。
查询的源是查询返回profile的任何内容,可能是一个实例。您可以通过 获取源。因此,如果包含您想要的内容,只需通过. 如果不是,请考虑将结果包装到一个对象中,该对象将包含您在子查询中需要的所有内容。userUserDataFetchingEnvironment#getSource()UserCustomerID((User) env.getSource()).getCustomerId()

3)使用共享上下文传递值

GraphQLContext如果您不自己提供自定义上下文,graphql-java 将为您提供一个实例。因此,在DataFetcherfor 中customer,您可以将其存储CustomerID到其中:

Customer customer = getCustomer();
GraphQLContext context = env.getContext();
context.put("CustomerID", customer.getId());

稍后,在DataFetcherfor 中profile,您可以从上下文中获取它:

GraphQLContext context = env.getContext();
context.get("CustomerID");

要提供自定义上下文,请在执行查询时传递它:

ExecutionInput input = ExecutionInput.newExecutionInput()
  .query(operation)
  .context(new ConcurrentHashMap<String, Object>())
  .build()
graphQL.execute(query, input);

而不是 a ConcurrentHashMap,您可以使用类型化对象,但您必须确保字段是volatilegetter/settersynchronized或其他线程安全的。

这种方式是有状态的,因此最难管理,所以只有在所有其他方法都失败时才使用它。

4)直接获取传递给父字段的参数(可能从graphql-java v11开始)

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

5) 使用本地上下文传递值(可能从 graphql-java v12 开始)

与其直接返回结果,不如将其包装成DataFetcherResult. 这样,您还可以将任何对象附加localContext为所有子对象都可以DataFetcher通过DataFetchingEnvironment#getLocalContext()

于 2017-05-25T11:17:31.470 回答