GraphQL解决了多个接口

时间:2018-01-17 22:03:52

标签: graphql graph-databases graphql-js

我正在使用原生图表数据库。

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

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

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

1 个答案:

答案 0 :(得分:1)

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

在一天结束时,如果您的目的是返回可能属性的子集(基于Pokemon的类型或类型),最简单的解决方案可能是将所有可能的属性放入{{1}的字段中键入并且不担心尝试围绕类型实现接口。这样可以在响应中实现所需的平面数据结构。最大的缺点是,作为响应的一部分,您可能会返回大量的空字段。

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