nestjs 基础GraphQL 指令

316 阅读1分钟

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);
}

小结

  1. NestJS 中的指令使用范围
  2. 自定义指令的行为
  3. 使用自定义指令