Skip to main content

接口

与许多类型系统一样,GraphQL 支持接口。 接口是一个抽象类型,它包含一组字段,类型必须包含这些字段以实现接口(阅读更多)。

代码优先方式

在使用首选代码方式时,通过创建一个由 @nestjs/graphql 包导出的 @InterfaceType() 装饰器注释的抽象类来定义 GraphQL 接口。

import { Field, ID, InterfaceType } from '@nestjs/graphql';

@InterfaceType()
export abstract class Character {
@Field((type) => ID)
id: string;

@Field()
name: string;
}
warning

无法使用 TypeScript 接口定义 GraphQL 接口。

这将导致生成 SDL 的 GraphQL 模式的以下部分:

interface Character {
id: ID!
name: String!
}

现在,要实现 Character 接口,请使用 implements 键:

@ObjectType({
implements: () => [Character],
})
export class Human implements Character {
id: string;
name: string;
}
tip

@ObjectType() 装饰器是从 @nestjs/graphql 包导出的。

库生成的默认 resolveType() 函数根据从解析器方法返回的值提取类型。 这意味着您必须返回类实例(不能返回字面的 JavaScript 对象)。

要提供自定义 resolveType() 函数,请将 resolveType 属性传递给传递给 @InterfaceType() 装饰器的选项对象, 如下所示:

@InterfaceType({
resolveType(book) {
if (book.colors) {
return ColoringBook;
}
return TextBook;
},
})
export abstract class Book {
@Field((type) => ID)
id: string;

@Field()
title: string;
}

接口解析器

到目前为止,使用接口,您只能与对象共享字段定义。 如果您还想共享实际的字段解析器实现,可以创建一个专用的接口解析器, 如下所示:

import { Resolver, ResolveField, Parent, Info } from '@nestjs/graphql';

@Resolver(type => Character) // 提醒:Character 是一个接口
export class CharacterInterfaceResolver {
@ResolveField(() => [Character])
friends(
@Parent() character, // 实现 Character 接口的已解析对象
@Info() { parentType }, // 实现 Character 接口的对象类型
@Args('search', { type: () => String }) searchTerm: string,
) {
// 获取角色的朋友
return [];
}
}

现在,friends字段解析器会自动注册到所有实现 Character 接口的对象类型中。

模式优先方式

在模式优先方式中,只需创建一个带有 SDL 的 GraphQL 接口。

interface Character {
id: ID!
name: String!
}

然后,您可以使用生成类型的功能(如快速入门章节所示)生成相应的 TypeScript 定义:

export interface Character {
id: string;
name: string;
}

接口在解析器映射中需要一个额外的 __resolveType 字段,以确定接口应解析为哪种类型。 让我们创建一个 CharactersResolver 类并定义 __resolveType 方法:

@Resolver('Character')
export class CharactersResolver {
@ResolveField()
__resolveType(value) {
if ('age' in value) {
return Person;
}
return null;
}
}
tip

所有装饰器都是从 @nestjs/graphql 包导出的。