如何用Pothos结合Prisma与PostgreSQL正确暴露日期时间字段
规范解决Pothos暴露Prisma DateTime字段的问题
问题原因
Pothos 默认没有内置 DateTime 标量类型,直接在 expose 中指定 type: 'DateTime' 或 Date 时,框架无法找到对应的类型实现,因此抛出 Ref DateTime has not been implemented 错误。
两种规范解决方案
方案一:使用官方 Date 插件(推荐)
借助 @pothos/plugin-date 插件快速添加 DateTime 标量,并通过 Prisma 插件自动完成类型映射:
- 安装插件
npm install @pothos/plugin-date
- 在 Builder 中注册插件
import { SchemaBuilder } from '@pothos/core'; import PrismaPlugin from '@pothos/plugin-prisma'; import DatePlugin from '@pothos/plugin-date'; import { prisma } from './prisma/client'; const builder = new SchemaBuilder({ plugins: [PrismaPlugin, DatePlugin], prisma: { client: prisma, }, });
- 暴露 DateTime 字段
插件会自动关联 Prisma 的DateTime类型到 GraphQL 的DateTime标量,两种写法任选其一即可:
builder.prismaObject('Course', { fields: (t) => ({ id: t.exposeID('id'), // 写法一:使用专门的 exposeDateTime 方法 createdAt: t.exposeDateTime('createdAt'), updatedAt: t.exposeDateTime('updatedAt'), // 写法二:直接 expose,插件自动推断类型 // createdAt: t.expose('createdAt'), // updatedAt: t.expose('updatedAt'), }), });
方案二:手动定义 DateTime 标量
如果不想依赖额外插件,可以手动实现 DateTime 标量:
- 定义标量类型
import { Kind } from 'graphql'; const DateTime = builder.scalarType('DateTime', { // 序列化:将 Date 对象转为 ISO 字符串返回给客户端 serialize: (value) => value.toISOString(), // 解析客户端传入的字符串为 Date 对象 parseValue: (value) => new Date(value), // 解析 GraphQL 字面量 parseLiteral: (ast) => { if (ast.kind === Kind.STRING) { return new Date(ast.value); } return null; }, });
- 暴露字段时指定自定义标量
builder.prismaObject('Course', { fields: (t) => ({ id: t.exposeID('id'), createdAt: t.expose('createdAt', { type: DateTime }), updatedAt: t.expose('updatedAt', { type: DateTime }), }), });
为什么临时方案不规范
你之前用 @ts-ignore + exposeString 的写法,本质是把 Date 对象转成字符串返回,但丢失了 GraphQL 中 DateTime 标量的类型校验和自动序列化/解析能力,不符合 GraphQL 类型系统的规范。
内容的提问来源于stack exchange,提问作者Atlante Avila
相关产品推荐
相关产品推荐

