如何在GraphQL中扩展类型?

atk*_*yla 9 types graphql

例如,a PetAnimal带有owner和的name

type Animal {
  species: String
}

type Pet extends Animal {
  owner: Owner
  name: String
}
Run Code Online (Sandbox Code Playgroud)

dpi*_*pix 18

虽然您无法创建子类/子类型,但您可以使用接口进行某种形式的继承: https: //graphql.org/learn/schema/#interfaces

上面链接中的示例:

interface Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
}
Run Code Online (Sandbox Code Playgroud)
type Human implements Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
  starships: [Starship]
  totalCredits: Int
}
 
type Droid implements Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
  primaryFunction: String
}
Run Code Online (Sandbox Code Playgroud)

查询时可以为不同的实现指定特定的字段

hero(episode: $ep) {
    name
    ... on Droid {
      primaryFunction
    }
    ... on Human {
      totalCredits
    }
  }
Run Code Online (Sandbox Code Playgroud)


Dan*_*scu 5

GraphQL规范June2018稳定版本开始,对象类型可以扩展另一种对象类型:

对象类型扩展用于表示从某种原始类型扩展过来的类型。例如,这可能用于表示本地数据

在您的示例中

type Animal {
  species: String
}

extend type Animal {
  owner: Owner
  name: String
}
Run Code Online (Sandbox Code Playgroud)

这本身不是继承;而是继承。您只能扩展基本类型,而不能基于它创建新类型。注意,新类型没有名称。现有Animal类型已扩展。

graphql.org文件没有提及任何东西extend,但文档是无可否认的低迷和正在转变,从Facebook的所有权转让给Linux基金会。JavaScript参考实现不完全支持扩展,但是由于您已经标记了问题,因此可以使用graphql-tools,它可以

type Animal {
  species: String
}

extend type Animal {
  owner: Owner
  name: String
}
Run Code Online (Sandbox Code Playgroud)

有关实际的类型继承,请参见graphql-s2s库

  • 那么,需要明确的是,扩展类型就像将另一个值推送到现有数组上一样?就像你可以写 `const foo = [1, 2];`,或者你可以写 `const foo = [1]; foo.push(2);` ...您可以编写一个类型def,或者您可以编写一个类型def并稍后扩展它?如果是这样,为什么有人会使用“extend”?将类型的定义分成两个不同的地方有什么价值? (2认同)

Ash*_*dem 3

目前这在 GraphQL 中是不可能的,但是有一个实验包可能对此目的有用。

https://github.com/Sydsvenskan/node-graphql-partials

参见示例:

partial LinkFields {
  links(
    rel: String
    type: String
  ): [Link]
}

partial DocumentFields using LinkFields {
  uuid: ID!

  # The document type, such as x-im/article
  type: String
  # If specified, then a list of the products to which this document's availability is limited
  products: [String]
  # The human readable name of the document, often used publicly to identify the document
  title: String

  # The specific path on the web page where this document is publicly available
  path: String

  # A single metadata block
  metaBlock(
    # The specific metadata block type to get
    type: String
  ): MetadataBlock
}

interface Document using DocumentFields {}

type AuthorDocument implements Document using DocumentFields {}
Run Code Online (Sandbox Code Playgroud)

结果是:

type AuthorDocument implements Document {
  links(
    rel: String
    type: String
  ): [Link]

  uuid: ID!

  # The document type, such as x-im/article
  type: String
  # If specified, then a list of the products to which this document's availability is limited
  products: [String]
  # The human readable name of the document, often used publicly to identify the document
  title: String

  # The specific path on the web page where this document is publicly available
  path: String

  # A single metadata block
  metaBlock(
    # The specific metadata block type to get
    type: String
  ): MetadataBlock
}
Run Code Online (Sandbox Code Playgroud)

由于这些只是字符串,您还可以做的是创建一些辅助函数来修改字符串并插入必要的字段。

如果您有兴趣关注 Github 上的讨论,可以查看以下问题。

https://github.com/graphql/graphql-js/issues/703