Java GraphQL-将字段值传递给对象的解析器 [英] Java GraphQL - Pass field values to resolver for objects

查看:102
本文介绍了Java GraphQL-将字段值传递给对象的解析器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望使用其他对象类型将字段值传递给已解析的字段.

如果我具有客户>用户>个人资料",则可以用另一种方式输入-如何将客户中的CustomerID字段值作为参数或变量传递给个人资料,以便正确解析?

解决方案

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

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

  {customer(id:3){用户{个人资料(id:3){名称}}}} 

2)从 source 对象

获取值

是封闭查询的结果.就您而言, customer 查询的源是根(无论您在查询执行时提供了什么,例如

  graphQL.execute(ExecutionInput.newExecutionInput().query(查询).root(根).建造()) 

user 查询的源是返回的任何 customer 查询,大概是某些 Customer 实例.
profile 查询的来源是 user 查询返回的任何内容,可能是 User 实例.您可以通过 DataFetchingEnvironment#getSource()保留源.因此,如果 User 包含您要使用的 CustomerID ,只需通过((User)env.getSource()).getCustomerId().如果没有,请考虑将结果包装到一个包含子查询中所需全部内容的对象中.

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

如果您未自行提供自定义上下文,则

graphql-java将为您提供 GraphQLContext 的实例.因此,在 customer DataFetcher 内部,您可以将 CustomerID 存储到其中:

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

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

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

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

  ExecutionInput输入= ExecutionInput.newExecutionInput().query(操作).context(新的ConcurrentHashMap< String,Object>()).建造()graphQL.execute(查询,输入); 

您可以使用类型化的对象来代替 ConcurrentHashMap ,但是必须确保字段是 volatile 或getters/setters同步化的或其他线程安全的方式.

这种方式是有状态的,因此最难管理,因此只有在所有其他方式都失败的情况下才使用它.

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

  ExecutionStepInfo stepInfo = dataFetchingEnvironment.getExecutionStepInfo();stepInfo.getParent().getArguments();//获取父参数 

5)使用 local 上下文传递值(自graphql-java v12起可能)

将结果包装到 DataFetcherResult 中,而不是直接返回结果.这样,您还可以通过 DataFetchingEnvironment#getLocalContext() localContext 附加到所有子 DataFetcher 可用的对象.>

I am looking to pass a field value to a resolved field using another object type.

Another way to put it if I have `Customer > User > Profile' - how can I pass the CustomerID field value that would be in customer to Profile as an argument or variable in order to resolve correctly?

解决方案

There's exactly 5 possibilities (as of graphql-java v12) to provide info to a resolver (DataFetcher) at any level:

1) Directly pass them in the query (possibly on multiple levels):

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

2) Get values from the source object

The source is the result of the enclosing query. In your case, the source for the customer query is the root (whatever you provided at the query execution time, e.g.

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

The source for the user query is whatever customer query returned, presumably some Customer instance.
The source for the profile query is whatever the user query returned, presumably a User instance. You can get a hold of the source via DataFetchingEnvironment#getSource(). So, if User contains the CustomerID you're after, just get it via ((User) env.getSource()).getCustomerId(). If not, consider wrapping the result into an object that would contain all you need in the sub-queries.

3) Pass the values around using the shared context

graphql-java will give you an instance of GraphQLContext if you don't provide a custom context by yourself. So, inside the DataFetcher for customer, you can store the CustomerID into it:

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

Later on, inside the DataFetcher for profile, you can get it from the context:

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

To provide a custom context, pass it when executing the query:

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

Instead of a ConcurrentHashMap, you could be using a typed object, but you'd have to make sure the fields are volatile or getters/setters synchronized or otherwise thread-safe.

This way is stateful, thus the hardest to manage, so use it only if all else fails.

4) Directly get the arguments passed to a parent field (possible as of graphql-java v11)

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

5) Pass the values around using the local context (possible as of graphql-java v12)

Instead of returning the result directly, wrap it into a DataFetcherResult. That way you can also attach any object as a localContext that will be available to all child DataFetchers via DataFetchingEnvironment#getLocalContext()

这篇关于Java GraphQL-将字段值传递给对象的解析器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆