【问题标题】:GraphQL resolve more than one interfaceGraphQL 解析多个接口
【发布时间】:2018-06-26 21:42:10
【问题描述】:

我正在使用本机图形数据库。

我的数据对象由许多较小的属性集组成,我希望能够一次查询所有这些属性,而无需在我的架构中添加额外的人工层。属性定义得很好,但它们的组成却没有。

假设我很容易(微不足道)从查询中输出此对象:

{
  "name": "Zapdos",
  "wingspan": 40,
  "airspeed": 120,
  "maxVoltage": 100000000
}

假设wingspanairVelocity 属性来自FlyingType 属性,maxVoltage 来自ElectricType 属性。这些和其他属性都已明确定义。其他口袋妖怪可能会混合和匹配适用于它们的属性,定义它们的所有组合可能没有意义。

理想场景

是否可以运行以下查询并返回相同格式的数据?

graphql-js 是否必须处理由resolveType 函数返回的数组?默认的resolveType 函数是否在调用isTypeOf 的第一个真值处停止?

query {
  Pokemon(name: "Zapdos") {
    name

    ... on isFlyingType {
      wingspan
      airVelocity
    }

    ... on isElectricType {
      maxVoltage
    }
  }
}

大概是什么情况

我真的需要用我需要的一切来构建一个新类型吗?我有许多属性组成我的数据,这意味着有很多类型来说明每种接口组合。例如。我必须执行以下操作吗?

type FlyingElectricPokemon implements isPokemon, isFlyingType, isElectricType {
  name: String!
  wingspan: Int
  airVelocity: Int
  maxVoltage: Int
}
query {
  Pokemon(name: "Zapdos") {
    name

    ... on FlyingElectricPokemon {
      wingspan
      airVelocity
      maxVoltage
    }
  }
}

我是否过于努力地避免 GraphQL 对我相当弱类型的图形数据进行强类型化?

解决方法,但增加了复杂性

我希望避免以下增加复杂性:

type Query {
  Pokemon(name: String): Pokemon
}

type Pokemon {
  name: String!
  attributes: [isAttribute!]
}

interface isAttribute {
  type: String!
}

type FlyingType implements isAttribute {
  type: String!
  wingspan: Int
}

type ElectricType implements isAttribute {
  type: String!
  maxVoltage: Int
}
query {
  Pokemon(name: "Zapdos") {
    name
    attributes {
      ... on FlyingType {
        wingspan
        airVelocity
      }
      ... on ElectricType {
        maxVoltage
      }
    }
  }
}

需要以下格式的数据

{
  "name": "Zapdos",
  "attributes": [
    { "type": "flying", "wingspan": 40 },
    { "type": "electric", "maxVoltage": 100000000 }
  ]
}

后一点我实际上是在处理Launchpad

【问题讨论】:

  • 我只能建议将相关类型分组到接口中,然后使用联合来弥补任何差距。当有选择时,我会选择工会,因为他们不需要太多的开销来推理。我不能给出具体的建议,因为你没有给出整个 API,但看起来有点尴尬。有时重新审视 1000 英尺的照片会很有帮助(如果您还没有投入太多)

标签: graphql graph-databases graphql-js


【解决方案1】:

这是一个有趣的场景。我认为 vanilla GraphQL 并没有真正提供实现您所描述的工具。问题是,最终,任何返回的对象都必须只有一种类型。 __resolveType 不能返回一个数组,即使你为多个类型声明了一个 __isTypeof 来为给定的对象评估 true,只有第一个评估为 true 的类型才会与该特定对象相关联。

归根结底,如果您的意图是返回可能属性的子集(基于口袋妖怪的类型),最简单的解决方案可能是将所有可能的属性放入 Pokemon 类型的字段中而不必担心尝试围绕类型实现接口。这实现了您在响应中想要的平面数据结构。最大的缺点是您可能会在响应中返回大量空字段。

您还可以查看 graphql-s2s 之类的东西,它支持类型继承和泛型。

【讨论】:

  • 谢谢。我还意识到,如果没有多态输入类型,我也无法创建突变。我现在正在研究如何将属性组(图上的每个边)查询到属性数组中。然后我可以为每个属性创建一个突变,将相同的 ID 传递给多个属性以更新父对象(图上的节点)。令人惊讶的是,这种突变的输入对象应该适用于 DBs 语言。
猜你喜欢
  • 2018-10-12
  • 2020-01-13
  • 2018-09-06
  • 2018-11-23
  • 2019-06-12
  • 2017-05-28
  • 2022-10-07
  • 2019-04-14
  • 2019-06-07
相关资源
最近更新 更多