GraphQL 解析多个接口

GraphQL resolve more than one interface

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

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

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

{
  "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 上工作。

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

归根结底,如果您的目的是 return 可能属性的子集(基于 Pokemon 的一种或多种类型),最简单的解决方案可能是将所有可能的属性放入字段中Pokemon 类型的,而不用担心尝试围绕这些类型实现接口。这实现了您在响应中想要的平面数据结构。最大的缺点是您可能会有大量空字段 returned 作为响应的一部分。

您还可以查看类似 graphql-s2s 的内容,它支持类型继承和泛型。