解析器
解析器
通常,您必须手动创建解析图。的@nestjs/graphql
包,在另一方面,产生解析器映射自动使用由装饰提供的元数据。为了学习库基础知识,我们将创建一个简单的作者API。首先,让我们在SDL中定义我们的类型:
type Author {
id: Int!
firstName: String
lastName: String
posts: [Post]
}
type Post {
id: Int!
title: String
votes: Int
}
type Query {
author(id: Int!): Author
}
我们的GraphQL架构包含暴露的单个查询author(id: Int!): Author
。现在,让我们创建一个AuthorResolver
。
@Resolver('Author')
export class AuthorResolver {
constructor(
private readonly authorsService: AuthorsService,
private readonly postsService: PostsService,
) {}
@Query()
async author(@Args('id') id: number) {
return await this.authorsService.findOneById(id
}
@ResolveProperty()
async posts(@Parent() author) {
const { id } = author;
return await this.postsService.findAll{ authorId: id }
}
}
提示
如果使用@Resolver()
装饰器,则不@Injectable()
必将类标记为,否则,这是必要的。
该@Resolver()
装饰不影响查询和突变(既不@Query()
也不@Mutation()
装饰)。它只通知Nest @ResolveProperty()
这个特定类中的每一个都有一个父类,Author
在这种情况下是一个类型(Author.posts
关系)。
通常,我们会使用类似getAuthor()
或getPosts()
方法名称。通过在装饰者的括号之间移动真实姓名,我们也可以轻松地做到这一点。
@Resolver('Author')
export class AuthorResolver {
constructor(
private readonly authorsService: AuthorsService,
private readonly postsService: PostsService,
) {}
@Query('author')
async getAuthor(@Args('id') id: number) {
return await this.authorsService.findOneById(id
}
@ResolveProperty('posts')
async getPosts(@Parent() author) {
const { id } = author;
return await this.postsService.findAll{ authorId: id }
}
}
提示
的@Resolver()
装饰可以在方法级别被使用。
装饰
您可能会注意到我们使用专用装饰器来引用以下参数。下面是提供的装饰器和它们代表的普通Apollo参数的比较。
@Root() 和 @Parent() | root/parent |
---|---|
@Context(param?: string) | context / context[param] |
@Info(param?: string) | info / info[param] |
@Args(param?: string) | args / args[param] |
模
一旦我们在这里完成,我们必须在AuthorResolver
某处注册,例如在新创建的内部AuthorsModule
。
JS
@Module{
imports: [PostsModule],
providers: [AuthorsService, AuthorResolver],
})
export class AuthorsModule {}
该GraphQLModule
会照顾反映了元数据和转化类到正确的解析器的自动映射。您应该注意的唯一事情是您需要在某处导入此模块,因此Nest将知道它AuthorsModule
确实存在。
分型
单独创建GraphQL类型和相应的TypeScript定义会产生不必要的冗余。最终,我们最终没有单一的事实来源,SDL内部的每一次变化都迫使我们调整接口。因此,该@nestjs/graphql
包提供了另一个有趣的功能,即使用抽象语法树(AST)自动生成TS定义。要启用它,只需自定义definitions
属性即可。
GraphQLModule.forRoot{
typePaths: ['./**/*.graphql'],
definitions: {
path: join(process.cwd(), 'src/graphql.ts'),
},
})
该src/graphql.ts
指示在何处保存打字稿输出。默认情况下,所有类型都转换为接口。但是,您可以通过将outputAs
属性更改为切换到类class
。
GraphQLModule.forRoot{
typePaths: ['./**/*.graphql'],
definitions: {
path: join(process.cwd(), 'src/graphql.ts'),
outputAs: 'class',
},
})
因此,它将生成以下文件:
export class Author {
id: number;
firstName?: string;
lastName?: string;
posts?: Post[];
}
export class Post {
id: number;
title?: string;
votes?: number;
}
export abstract class IQuery {
abstract author(id: number): Author | Promise<Author>;
}
类允许您使用装饰器
,这使得它们在验证方面非常有用。例如:
import { MinLength, MaxLength } from 'class-validator';
export class CreatePostInput {
@MinLength(3)
@MaxLength(50)
title: string;
}
注意
要启用输入(和参数)的自动验证,必须使用ValidationPipe
。