如何知道 Sangria GraphQL 中对象解析器中的请求字段

Posted

技术标签:

【中文标题】如何知道 Sangria GraphQL 中对象解析器中的请求字段【英文标题】:How to know requested fields in resolver of Object in Sangria GraphQL 【发布时间】:2017-05-10 13:30:20 【问题描述】:

我正在通过 Sangria GraphQL("org.sangria-graphql" %% "sangria" % "1.0.0-RC5") 构建 GrapQL 服务器

我不确定正常情况下是否需要它。但为了提高性能,我想在解析期间从客户端获取请求的字段。

例如,

如果您要求,

query Query
  FooObject
     fieldA
     fieldB
  

您的服务器可能会在 FooObject 对象解析器中解析

resolve = Ctx => DB.session
  .query("select fieldA, fieldB, FieldC, FieldD from DATA_TABLE")
  .map(entity => DataObject(entity.fieldA, entity.fieldB)  // By ORM Mapper
)

那么,

对象字段可以在 FooObject 对象的字段解析器中解析

Field("fieldA", type..., resolve = _.fieldA )
Field("fieldB", type..., resolve = _.fieldB )
Field("fieldC", type..., resolve = _.fieldC )
Field("fieldD", type..., resolve = _.fieldD )

然后,你可能会得到graphql结果


  data:
    FooObject:
      FieldA: "DataA"
      FieldB: "DataB"
    
  

我想要做的是,在对象解析器中解析期间,给出如下所示的字段提示。

resolve = Ctx => 
// Seq(FieldA[], FieldB[])
val requestedFields: Seq[Field[ ... ]] = Ctx.[__COLLECT_REQUESTED_FIELDS__]()

// "FieldA, FieldB"
val fetchingFieldInQuery:String = requestedFields.foldRight("")((acc, nextField) => acc + ", nextField" )

DB.session
   .query(s"select $fetchingFieldInQuery from DATA_TABLE")
    .map( entity => DataObject(entity.fieldA, entity.fieldB)) // By ORM Mapper

在这种情况下,我无法以某种方式提取客户端在解析器中请求的字段。 Ctx(context) 对象在我的调查中很好地显示了对象与请求无关的内容。有没有我提到的Ctx.[__COLLECT_REQUESTED_FIELDS__]() 之类的方法?

我可以通过每个字段解析器尝试通过在数据库中选择一列进行查询。但如果我已经知道请求的字段是什么,我可以在一个查询中完成它,它可以解决很多N+1 案例问题(因为***对象可以将所有嵌套对象带到查询中,它可能取决于数据库)

我知道GraphQL 仍然没有最佳实践。 可能存在比我尝试的更好的方法。购买以了解请求的字段有利于处理数据。

如果你知道,请告诉我。

谢谢。

【问题讨论】:

【参考方案1】:

Sangria 提供了一些功能,可以在您描述的场景中为您提供帮助。

首先是预测:http://sangria-graphql.org/learn/#projections

当您使用它时,字段将被自动收集并作为带有字段名称的树形式的参数提供给解析函数。文档本身没有示例,因此我建议您检查这些测试以了解它在实践中的工作原理:https://github.com/sangria-graphql/sangria/blob/master/src/test/scala/sangria/execution/ProjectorSpec.scala

关于 N+1 查询问题。我建议您查看描述延迟值解析的文档部分:http://sangria-graphql.org/learn/#deferred-value-resolution。我认为它在这方面也可以为您提供帮助。

【讨论】:

看来sangria-graphql.org 不再有效并重定向到一个狡猾的域。而是:sangria-graphql.github.io 是的@luke-chadwik — 遗憾的是,Oleg (@tenshi) 去世了,Sangria 项目的所有权已经转移。感谢您发布更新的链接。

以上是关于如何知道 Sangria GraphQL 中对象解析器中的请求字段的主要内容,如果未能解决你的问题,请参考以下文章

如何在 sangria-graphql 中执行突变?

如何在 Sangria 中使用 graphql 查询过滤列表响应

了解 Sangria-graphql 执行器

Sangria-graphql:将 derivedInputObjectType 作为变异参数传入时出错

sangria graphql 查询返回 1 个元素列表

Graphiql 中标记为非空的所有字段和参数:Sangria,scala