0

大家好。我正在使用 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 的一个实例。

一些实现细节。该模式是使用Schema.buildFromAstGraphQL 文档中的方法构建的,并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是 a JsObject,则取其名为 的 Json 字段context.field.name
  • 如果context.value是 a JsString,则将其解释为实体的 oid,使用上下文提供的句柄在商店中查找实体Ctx;该实体被检索为 a JsObject,并采用其名称为 的 Json 字段context.field.name

正如我所提到的,问题是不尊重内联片段。也许,我错过了一些东西。也许,不仅如此,resolveField其他一些事情也需要正确实施。也许,我的resolveField.

你有什么建议?在您看来,问题出在哪里?你会建议我做什么来解决这个问题?

4

1 回答 1

2

由于您使用的是泛型JsValue,因此您还需要覆盖DefaultAstSchemaBuilder.objectTypeInstanceCheck. 它应该告诉库特定JsValue是否属于特定的 GraphQL 类型。例如,如果您的实体 JSON 具有类似的字段,{"type": "Dataset", ...}则您需要根据提供的ObjectType名称检查它。

于 2017-08-03T23:26:02.613 回答