【发布时间】:2018-08-01 17:45:09
【问题描述】:
例如,Pet 是带有owner 和name 的Animal。
type Animal {
species: String
}
type Pet extends Animal {
owner: Owner
name: String
}
【问题讨论】:
例如,Pet 是带有owner 和name 的Animal。
type Animal {
species: String
}
type Pet extends Animal {
owner: Owner
name: String
}
【问题讨论】:
从June2018 stable version of the GraphQL spec开始,一个Object类型可以扩展另一个Object类型:
对象类型扩展用于表示从某个原始类型扩展而来的类型。例如,这可能用于表示本地数据
在你的例子中,
type Animal {
species: String
}
extend type Animal {
owner: Owner
name: String
}
这本身不是继承;您只能扩展基本类型,不能基于它创建新类型。请注意,新类型没有名称;现有的Animal 类型已扩展。
graphql.org documentation 没有提到任何关于extend 的内容,但文档是admittedly lackluster 并且是transitioned 来自Facebook 对Linux 基金会的所有权。
JavaScript 参考实现doesn't fully support extensions,但既然你已经标记了你的问题apollo-server,你可以使用graphql-tools,其中does:
const { graphql } = require('graphql');
const { makeExecutableSchema } = require('graphql-tools');
const typeDefs = `
type Person {
name: String!
}
extend type Person {
salary: Int
}
type Query {
person: Person
}
`;
const resolvers = {
Query: {
person: () => ({ name: "John Doe", salary: 1234 })
}
}
const schema = makeExecutableSchema({ typeDefs, resolvers });
graphql(schema, '{ person {name salary} }').then((response) => {
console.log(response);
});
对于实际的类型继承,请参阅graphql-s2s library。
【讨论】:
const foo = [1, 2];,或者你可以写const foo = [1]; foo.push(2);...你可以写一个类型def,或者你可以写一个类型def并在以后扩展它?如果是这样,为什么有人会使用extend?将你的类型定义分成两个不同的地方有什么价值?
虽然您不能创建子类/子类型,但您可以使用接口进行某种形式的继承:https://graphql.org/learn/schema/#interfaces
以上链接中的示例:
interface Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
}
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
}
查询时可以为不同的实现指定特定的字段
hero(episode: $ep) {
name
... on Droid {
primaryFunction
}
... on Human {
totalCredits
}
}
【讨论】:
目前这在 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 {}
结果:
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
}
由于这些只是字符串,您还可以创建一些辅助函数来修改字符串并插入必要的字段。
如果你有兴趣关注 Github 上的讨论,可以看看下面的 issue。
【讨论】:
extend type,这是可能的。
其他答案是正确的,这不是专门化的类型扩展。
请注意,类型扩展似乎有两种语法。根据Apollo Federation specification,graphql-java支持@extend语法。
在 Apollo 文档中,语法似乎是:
extend type Animal
但根据联邦规范,也支持另一种语法:
type Animal @key(fields: "id") @extends
一些框架似乎只支持@ 语法。
【讨论】: