GraphQL 指令
指令主要是影响 GraphQL 的查询过程和查询结果,类似于 nestjs 中的过滤器等功能。支持的默认指令:
- include
- skip
- deprecated
与 css 中一样,指令使用 @ 进行表示
指令使用范围
- 字段
- 字段解析器
- 输入和对象类型
- 查询
- 变异
- 订阅
NestJS/GraphQL中的指令
nestjs 中自定义指令依赖 apollo-server 的 SchemaDirectiveVisitor 接口,老样子我们的指令分为定义和使用两部分;
自定义指令
自定义指令要实现 visitFieldDefinition 方法,此方法接收 field 作为参数。我们要操作的就是 field, field 对象实现 resolve, resolve 方法调用后的 result 做我们想要的指令操作。然后将 result 返回
import { SchemaDirectiveVisitor } from 'apollo-server';
import { defaultFieldResolver, GraphQLField } from 'graphql';
export class UpperCaseDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field: GraphQLField<any, any>) {
const { resolve = defaultFieldResolver } = field;
field.resolve = async function(...args) {
const result = await resolve.apply(this, args);
if (typeof result === 'string') {
return result.toUpperCase();
}
return result;
};
}
}
使用自定义指令
在 GraphQLModule 中注册指令,schemaDirectives 对象映射自定指令
// 注册
GraphQLModule.forRoot({
// ...
schemaDirectives: {
upper: UpperCaseDirective,
},
});
// 用于字段
@Directive('@upper')
@Field()
title: string;
// 用于查询
@Directive('@deprecated(reason: "This query will be removed in the next version")')
@Query(returns => Author, { name: 'author' })
async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
return this.authorsService.findOneById(id);
}
小结
- NestJS 中的指令使用范围
- 自定义指令的行为
- 使用自定义指令