Java GraphQL - 将字段值传递给对象的解析器
Posted
技术标签:
【中文标题】Java GraphQL - 将字段值传递给对象的解析器【英文标题】:Java GraphQL - Pass field values to resolver for objects 【发布时间】:2017-10-24 21:05:48 【问题描述】:我希望使用另一种对象类型将字段值传递给已解析的字段。
如果我有“客户 > 用户 > 个人资料”,另一种说法 - 我如何将客户中的客户 ID 字段值作为参数或变量传递给个人资料以便正确解析?
【问题讨论】:
没有代码或其他有关您正在使用的信息的信息。我没有使用任何用于 Java 的 GraphQL 库,所以 YMMV 但通常您会将此信息附加到您为每个解析点返回的值中。当你从Customer
得到User
时,它应该携带来自Customer
的一些(或全部)数据,同样也传送到Profile
,所以(天真地)你可能会做一些事情((Profile)resolveParams.getSource()).getUser().getCustomer().getId()
【参考方案1】:
正好有 5 种可能性(从 graphql-java v12 开始)向任何级别的解析器 (DataFetcher
) 提供信息:
1) 直接在查询中传递它们(可能在多个级别上):
customer(id: 3)
user
profile(id: 3)
name
2) 从源对象中获取值
source 是封闭查询的结果。
在您的情况下,customer
查询的来源是根(无论您在查询执行时提供什么,例如
graphQL.execute(ExecutionInput.newExecutionInput()
.query(query)
.root(root)
.build())
user
查询的来源是返回的任何 customer
查询,可能是一些 Customer
实例。profile
查询的来源是 user
查询返回的任何内容,可能是 User
实例。
您可以通过DataFetchingEnvironment#getSource()
获取源代码。因此,如果User
包含您想要的CustomerID
,只需通过((User) env.getSource()).getCustomerId()
获取它。如果没有,请考虑将结果包装到一个对象中,该对象将包含您在子查询中需要的所有内容。
3) 使用共享上下文传递值
graphql-java 如果您不自己提供自定义上下文,将为您提供GraphQLContext
的实例。因此,在customer
的DataFetcher
中,您可以将CustomerID
存储到其中:
Customer customer = getCustomer();
GraphQLContext context = env.getContext();
context.put("CustomerID", customer.getId());
稍后,在DataFetcher
for profile
中,您可以从上下文中获取它:
GraphQLContext context = env.getContext();
context.get("CustomerID");
要提供自定义上下文,请在执行查询时传递它:
ExecutionInput input = ExecutionInput.newExecutionInput()
.query(operation)
.context(new ConcurrentHashMap<String, Object>())
.build()
graphQL.execute(query, input);
您可以使用类型化对象而不是 ConcurrentHashMap
,但您必须确保字段是 volatile
或 getters/setters synchronized
或其他线程安全的。
这种方式是有状态的,因此最难管理,所以只有在其他方法都失败时才使用它。
4) 直接获取传递给父字段的参数(可能从 graphql-java v11 开始)
ExecutionStepInfo stepInfo = dataFetchingEnvironment.getExecutionStepInfo();
stepInfo.getParent().getArguments(); // get the parent arguments
5) 使用 local 上下文传递值(可能从 graphql-java v12 开始)
不是直接返回结果,而是将其包装成DataFetcherResult
。这样,您还可以将任何对象附加为 localContext
,所有子 DataFetcher
s 都可以通过 DataFetchingEnvironment#getLocalContext()
使用该对象
【讨论】:
非常感谢!您能否添加有关使用一种或另一种方式的一些用例的信息?在所有这些方法中,哪种方式更可取? @Max 如果可以自然地将值表示为父级的属性,#2 是最简单的。如果不是,并且值很简单(不需要反序列化),#4 很好。除了这些,#5 很好。 #1 和 #3 不太可取。以上是关于Java GraphQL - 将字段值传递给对象的解析器的主要内容,如果未能解决你的问题,请参考以下文章
如何在 GraphQL 突变中使用 FaunaDB 将数组传递给字段
如何将 JSONObject 值分配给 graphql 模式文件中的字段?