【发布时间】:2018-01-11 15:49:57
【问题描述】:
大家好。我正在使用 sangria-graphql,一切正常……除了内联片段。我在架构中有以下类型:
interface Entity {
oid: ID!
}
type Dataset implements Entity {
oid: ID!
name: String
... (other fields)
}
... (other types implementing Entity)
type Issue {
entity: Entity!
... (other fields)
}
type Query {
validate(many arguments): [Issue!]
... (other queries)
}
我发送这样的查询:
{
validate(many arguments) {
entity {
oid
... on Dataset {
name
}
}
}
即使返回的 oid 是 Dataset 实例的 oid,也不会返回任何名称。就好像解析器不知道这是 Dataset 的一个实例,只将其视为 Entity 的一个实例。
一些实现细节。该模式是使用 GraphQL 文档中的 Schema.buildFromAst 方法构建的,并实现了 resolveField 方法:
import sangria.schema._
import sangria.ast.Document
import play.api.libs.json._
// document is an instance of Document
lazy val schema: Schema[Ctx, Any] =
Schema.buildFromAst(document, new DefaultAstSchemaBuilder[Ctx] {
override def resolveField(typeDefinition: TypeDefinition,
fieldDefinition: FieldDefinition) =
typeDefinition.name match {
case "Mutation" => context =>
fieldDefinition.name match {
... // cases for specific mutations
}
case "Query" => context =>
fieldDefinition.name match {
case "validate" =>
... // implementation that returns a Seq[JsValue],
// where the Json values are serializations of Issue
... // cases for other queries
}
case _ => context =>
... // resolve the sub-selection fields as described below
}
}
子选择字段解析如下:
- 如果
context.value是JsObject,则取其名称为context.field.name的Json字段; - 如果
context.value是JsString,那么它被解释为一个Entity的oid,使用Ctx上下文提供的句柄在store中查找该实体;实体被检索为JsObject,并取其名称为context.field.name的Json字段。
正如我所提到的,问题是内联片段没有得到尊重。也许,我错过了一些东西。也许,不仅仅是resolveField,还需要正确实施其他一些东西。也许,我对resolveField 的实现有问题。
你有什么建议?在您看来,问题出在哪里?你会建议我做什么来解决这个问题?
【问题讨论】: