为什么GraphQL` implements`需要复制字段,这是强制性的吗?如果是,那么潜在的原因是什么?

时间:2017-04-17 10:19:59

标签: graphql graphql-js

为什么GraphQL implements关键字需要复制字段,这是强制性的吗?与文档中的示例一样:

enum Episode { NEWHOPE, EMPIRE, JEDI }

interface Character {
  id: String
  name: String
  friends: [Character]
  appearsIn: [Episode]
}

type Human implements Character {
  id: String
  name: String
  friends: [Character]
  appearsIn: [Episode]
  homePlanet: String
}

type Droid implements Character {
  id: String
  name: String
  friends: [Character]
  appearsIn: [Episode]
  primaryFunction: String
}

如果是,那么潜在的原因是什么?

因为如果我必须复制,如果我改变那么我需要改变到处......

2 个答案:

答案 0 :(得分:9)

是的,根据当前的spec

,这是强制性的
  

对象类型必须包含接口中定义的每个字段的同名字段。

它允许您在派生类型中指定更精确的字段类型。可以将字段更改为非null或更改为接口或联合的某个特定子类型。举个例子,让我们假设人类只与其他人类成为朋友,而对于机器人则是如此。然后以下架构有效。

interface Character {
  id: String
  name: String
  friends: [Character]
  appearsIn: [Episode]
}

type Human implements Character {
  id: String
  name: String
  friends: [Human] # <- notice Human here
  appearsIn: [Episode]
  homePlanet: String
}

type Droid implements Character {
  id: String
  name: String
  friends: [Droid!]! # <- specified Droid here + added not null
  appearsIn: [Episode]
  primaryFunction: String
}

对象字段可能包含未在接口字段中定义的其他参数(但不得要求任何其他参数)。

查看规范以获取更多详细信息:Object type validation

答案 1 :(得分:2)

是的,这是强制性的。如果它有帮助,可以将其视为类似于Java类和接口。接口具有类型签名,但不能具有实现。在您编写所有实现的类中,类型签名会重复出现。这使您能够在类型签名中选择子类型或协变类型,因此它们可能完全相同。

现在假设您正在使用graphql-js中的JavaScript对象创建GraphQL架构。接口只是字段名称和类型。对象类型定义本身具有“实现”或resolveresolveType以及实际使其成为可执行模式的其他属性。

然而,您的示例使用的是模式语言,它根本没有“实现”。所以他们几乎是彼此的精确重复。你不一定每次都需要拼写,你可以使用字符串插值来共享界面的一部分。

const characterFields = `
  id: String
  name: String
  friends: [Character]
  appearsIn: [Episode]
`

const typeDefs = `
  interface Character {
    ${characterFields}
  }

  type Human Implements Character {
    ${characterFields}
    homePlanet: String
  }
`

编辑:类似于Java比较,字段可能不是完全相同的类型。正如RomanHotsiy指出的那样,你可以使类型不可为空或使用多态类型的子类型。

相关问题