我正在使用Sangria GraphQL构建GrapQL服务器(“org.sangria-graphql”%%“sangria”%“1.0.0-RC5”)
我不确定它是否正常需要 . 但为了提高性能,我希望在解析期间从客户端获取所请求的字段 .
例如,
如果你要求,
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)
对象在我的调查中显示了The Object与请求的关系 . 有没有像我提到的方法 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 . 我认为它也可以在这方面帮助你 .