如何在NestJS的.graphql文件导入自定义标量并在解析器中使用?
如何在NestJS GraphQL的Resolver中使用自定义DateScalar
我帮你梳理下在那个12-graphql-apollo示例项目里,怎么在cats.resolvers.ts中使用自定义的DateScalar,分几个关键步骤来:
1. 确保DateScalar的正确实现
首先确认你的date.scalar.ts已经正确继承了GraphQLScalarType,完成序列化、解析值和解析字面量的核心逻辑,示例如下:
import { GraphQLScalarType, Kind } from 'graphql'; export const DateScalar = new GraphQLScalarType({ name: 'Date', description: '自定义日期标量类型,处理时间戳与Date对象的转换', serialize(value: Date) { return value.getTime(); // 把Date对象转成时间戳返回给客户端 }, parseValue(value: number) { return new Date(value); // 把客户端传来的时间戳转成Date对象 }, parseLiteral(ast) { if (ast.kind === Kind.INT) { return new Date(parseInt(ast.value, 10)); // 处理GraphQL字面量中的整数 } return null; }, });
2. 将DateScalar注册到NestJS GraphQL模块
在AppModule(或者CatsModule)里,需要把自定义标量注册到GraphQL模块中,让NestJS能识别并关联它:
import { Module } from '@nestjs/common'; import { GraphQLModule } from '@nestjs/graphql'; import { DateScalar } from './date.scalar'; import { CatsModule } from './cats/cats.module'; @Module({ imports: [ GraphQLModule.forRoot({ autoSchemaFile: 'schema.gql', // 自动生成合并后的全局schema文件 scalarsMap: [{ type: Date, scalar: DateScalar }], // 把JS原生Date类型映射到自定义标量 }), CatsModule, ], providers: [DateScalar], // 将标量作为提供者注入,确保模块能访问到 }) export class AppModule {}
3. 在GraphQL Schema文件中声明标量
因为你用的是schema-first模式(存在cats.graphql文件),需要先在该文件里声明自定义标量,之后才能在类型定义中使用:
# cats.graphql scalar Date type Cat { id: ID! name: String! age: Int! birthDate: Date # 这里使用自定义的Date标量 } type Query { getCat(id: ID!): Cat getCurrentDate: Date # 新增一个返回日期的查询示例 }
4. 在cats.resolvers.ts中使用DateScalar
现在就可以在Resolver里直接使用Date类型(或者显式指定DateScalar)来处理字段和参数了:
方式一:隐式使用(推荐)
只要标量已完成注册,直接用JS的Date类型即可,NestJS会自动关联到DateScalar处理序列化和解析:
import { Resolver, Query, Args } from '@nestjs/graphql'; import { CatsService } from './cats.service'; import { Cat } from './models/cat.model'; @Resolver(() => Cat) export class CatsResolver { constructor(private readonly catsService: CatsService) {} @Query(() => Cat) async getCat(@Args('id') id: string) { return this.catsService.findOne(id); // 假设返回的Cat对象包含birthDate: Date字段 } @Query(() => Date) async getCurrentDate() { return new Date(); // 自动通过DateScalar序列化为时间戳返回给客户端 } }
方式二:显式指定标量
如果需要明确指定使用DateScalar,可以在装饰器中显式声明:
import { Resolver, Query, Args, Field, ObjectType } from '@nestjs/graphql'; import { CatsService } from './cats.service'; import { DateScalar } from '../date.scalar'; @ObjectType() export class Cat { // 在实体字段中显式指定使用自定义标量 @Field(() => DateScalar) birthDate: Date; } @Resolver(() => Cat) export class CatsResolver { constructor(private readonly catsService: CatsService) {} // 在查询参数中显式指定使用自定义标量 @Query(() => [Cat]) async getCatsByBirthDate( @Args('birthDate', { type: () => DateScalar }) birthDate: Date ) { return this.catsService.findByBirthDate(birthDate); } }
这样操作后,你的自定义DateScalar就能在Resolver和GraphQL Schema中正常工作了。
内容的提问来源于stack exchange,提问作者Crewnie Master
相关产品推荐
相关产品推荐

