【问题标题】:sangria-graphql: Inline Fragments Not Resolvedsangria-graphql:内联片段未解决
【发布时间】: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.valueJsObject,则取其名称为context.field.name的Json字段;
  • 如果context.valueJsString,那么它被解释为一个Entity的oid,使用Ctx上下文提供的句柄在store中查找该实体;实体被检索为JsObject,并取其名称为context.field.name的Json字段。

正如我所提到的,问题是内联片段没有得到尊重。也许,我错过了一些东西。也许,不仅仅是resolveField,还需要正确实施其他一些东西。也许,我对resolveField 的实现有问题。

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

【问题讨论】:

    标签: scala graphql sangria


    【解决方案1】:

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

    【讨论】:

    • 谢谢!看起来像我正在寻找的方法。
    • @silverberry 我也需要这个,因为我面临着类似的问题。但是,我不明白如何准确地覆盖这个方法。你能帮忙分享一些代码sn-p吗?
    猜你喜欢
    • 2017-06-10
    • 2017-06-24
    • 2020-04-30
    • 1970-01-01
    • 2017-09-25
    • 1970-01-01
    • 2018-04-07
    • 2017-05-10
    • 2020-11-28
    相关资源
    最近更新 更多