加入我们,从10月8日至10日在纽约市,了解关于GraphQL联邦和API平台工程的最新的技巧、趋势和新闻。加入我们,参加2024年纽约市的GraphQL峰会
文档
免费开始

联合和接口

抽象架构类型


联合体接口是抽象类型,允许模式返回多种之一。

联合体类型

当你定义一个联合体类型时,声明哪些对象类型包含在联合体中:

union Media = Book | Movie

一个字段可以有一个联合体(或该联合体的列表)作为其返回类型。在这种情况下,它可以返回联合体中包含的任何

type Query {
allMedia: [Media] # This list can include both Book and Movie objects
}

联合体中包含的所有类型必须是对象类型(不是,输入类型等)。包含的类型不需要共享任何

示例

以下模式定义了一个SearchResult联合体类型,可以返回BookAuthor

union SearchResult = Book | Author
type Book {
title: String!
}
type Author {
name: String!
}
type Query {
search(contains: String): [SearchResult!]
}

The SearchResult联合体允许Query.search返回包含BookAuthor的列表。

查询联合体

不知道如果字段的返回类型是联合类型时,该字段会返回哪种对象类型。为了处理这种情况,可以查询包含多个可能类型的子字段。

以上是有效的查询:

query GetSearchResults {
search(contains: "Shakespeare") {
# Querying for __typename is almost always recommended,
# but it's even more important when querying a field that
# might return one of multiple types.
__typename
... on Book {
title
}
... on Author {
name
}
}
}

这个查询使用了内联片段来获取结果对象的title(如果是Book),或它的name(如果是Author)。Web 客户端可以通过传递可能的类型选项来了解这种多态关系。

以上查询的有效结果如下:

{
"data": {
"search": [
{
"__typename": "Book",
"title": "The Complete Works of William Shakespeare"
},
{
"__typename": "Author",
"name": "William Shakespeare"
}
]
}
}

解决联合类型

在阅读本节之前,请先学习了解解器

要完全解析一个联合类型,Apollo Server需要指定返回联合类型的哪种类型。。要实现这一点,您需要在Resolver映射中为联合类型定义一个__resolveType函数。

__resolveType函数负责确定对象的对应GraphQL类型,并以字符串形式返回该类型的名称。它可以使用任何逻辑来完成此操作,例如:

  • 检查联合类型中是否包含特定类型的唯一字段
  • 使用instanceof,如果JavaScript对象的类型与其GraphQL对象类型相关

以下是上述SearchResult__resolveType函数的基本实现:

const resolvers = {
SearchResult: {
__resolveType(obj, contextValue, info){
// Only Author has a name field
if(obj.name){
return 'Author';
}
// Only Book has a title field
if(obj.title){
return 'Book';
}
return null; // GraphQLError is thrown
},
},
Query: {
search: () => { ... }
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
});
const { url } = await startStandaloneServer(server);
console.log(`🚀 Server ready at: ${url}`);

如果__resolveType函数返回的任何值都不是有效的类型名称,则相关操作会产生GraphQL错误。

接口类型

接口指定一个多对象类型可以包含的字段集

interface Book {
title: String!
author: Author!
}

如果一个对象类型实现了接口,那么它必须包含该接口的所有字段:

type Textbook implements Book {
title: String! # Must be present
author: Author! # Must be present
courses: [Course!]!
}

一个字段可以作为接口(或该接口的列表)作为其返回类型。在这种情况下,它可以返回实现了该接口的任何对象类型:

type Query {
books: [Book!]! # Can include Textbook objects
}

示例

以下模式定义了一个Book接口,以及两个实现它的对象类型:

interface Book {
title: String!
author: Author!
}
type Textbook implements Book {
title: String!
author: Author!
courses: [Course!]!
}
type ColoringBook implements Book {
title: String!
author: Author!
colors: [String!]!
}
type Query {
books: [Book!]!
}

在这个模式中,Query.books返回一个可以包含Textbook和ColoringBook的列表。

查询接口

如果一个字段的返回类型是接口,那么客户端可以查询该接口的任何包含的字段:

query GetBooks {
books {
title
author
}
}

客户端还可以查询接口中不包含的子字段:

query GetBooks {
books {
# Querying for __typename is almost always recommended,
# but it's even more important when querying a field that
# might return one of multiple types.
__typename
title
... on Textbook {
courses {
# Only present in Textbook
name
}
}
... on ColoringBook {
colors # Only present in ColoringBook
}
}
}

查询 使用 内联片段 来获取一本 Book 的课程(如果是 Textbook)或其 colors(如果是 ColoringBook)。可以通过传递 possibleTypes 选项来告知网页客户端这种多态关系。

以上查询的有效结果如下:

{
"data": {
"books": [
{
"__typename": "Textbook",
"title": "Wheelock's Latin",
"courses": [
{
"name": "Latin I"
}
]
},
{
"__typename": "ColoringBook",
"title": "Oops All Water",
"colors": ["Blue"]
}
]
}
}

解决一个接口

在阅读本节之前,请先学习了解解器

与联合类型一样Apollo Server 需要接口来定义一个 __resolveType 函数以确定返回哪种实现 对象类型

以下是上面定义的 Book 接口的 __resolveType 函数的例子:

const resolvers = {
Book: {
__resolveType(book, contextValue, info){
// Only Textbook has a courses field
if(book.courses){
return 'Textbook';
}
// Only ColoringBook has a colors field
if(book.colors){
return 'ColoringBook';
}
return null; // GraphQLError is thrown
},
},
Query: {
books: () => { ... }
},
};
上一页
Schema基础知识
下一页
自定义标量
评估文章评估在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.,又名Apollo GraphQL。

隐私政策

公司