使用Pothos GraphQL与Prisma插件时遇TypeError:Post/User需定义字段
解决Pothos + Prisma集成中"Type Post/User must define one or more fields"错误
问题描述
我正在开发一款社交应用,技术栈如下:
- 前端及SSR:NextJS
- 服务端:GraphQL-Yoga
- GraphQL类型安全:Pothos
- 数据库:Prisma
已完成官方文档的集成步骤,但出现以下错误:
ERR Error: Type Post must define one or more fields. Type User must define one or more fields.
GraphQL Yoga界面也显示相同错误。我已在类型定义文件中为Post和User明确声明了所有字段,不清楚错误原因。
应用目录结构:
api ┣ auth ┃ ┗ [...nextauth] ┃ ┃ ┣ authorization.ts ┃ ┃ ┣ options.ts ┃ ┃ ┗ route.ts ┗ graphql ┃ ┣ types ┃ ┃ ┣ Post.ts ┃ ┃ ┣ Profile.ts ┃ ┗ ┗ User.ts ┃ ┣ builder.ts ┃ ┣ route.ts ┃ ┗ schema.ts
Post.ts代码(User.ts结构类似):
//./api/graphql/types/Post.ts import prisma from "@/prisma/database"; import { builder } from "../builder"; export const Post = builder.prismaObject("Post", { fields: (t) => ({ id: t.exposeString("id"), visibleTo: t.exposeString("visibleTo"), published: t.exposeBoolean("published"), hasImage: t.exposeBoolean("hasImage"), hasVideo: t.exposeBoolean("hasVideo"), createdAt: t.expose("createdAt", { type: Date }), updatedAt: t.expose("updatedAt", { type: Date }), title: t.exposeString("title", { nullable: true }), content: t.exposeString("content", { nullable: true }), likes: t.relation("likes"), comments: t.relation("comments"), media: t.relation("media"), category: t.relation("category"), viewCount: t.exposeInt("viewCount"), author: t.relation("author"), }), }); builder.queryField("posts", (t) => t.prismaField({ type: ["Post"], resolve: async (query, root, args, ctx, info) => { return prisma.post.findMany({ ...query }); }, }) ); builder.queryFields((t) => ({ post: t.prismaField({ type: "Post", args: { id: t.arg.string({ required: true }), }, resolve: async (query, root, args, ctx, info) => { return prisma.post.findUniqueOrThrow({ where: { id: args.id, }, }); }, }), }));
GraphQL路由文件(route.ts):
// pages/api/graphql/route.ts import { createYoga } from "graphql-yoga"; import type { NextApiRequest, NextApiResponse } from "next"; import { schema } from "./schema"; const { handleRequest } = createYoga<{ req: NextApiRequest; res: NextApiResponse; }>({ schema, graphqlEndpoint: "/api/graphql", fetchAPI: { Response: Response }, }); export { handleRequest as GET, handleRequest as POST, handleRequest as OPTIONS, };
可能的原因及解决步骤
1. 类型定义文件未被正确导入
检查schema.ts文件,确认是否导入了所有类型定义文件。Pothos需要显式导入才能将类型包含进最终Schema:
// api/graphql/schema.ts import { builder } from "./builder"; // 必须导入所有类型文件 import "./types/Post"; import "./types/User"; import "./types/Profile"; export const schema = builder.toSchema({});
遗漏导入会导致Pothos无法识别字段定义,触发错误。
2. Prisma Schema与Pothos类型不匹配
检查prisma/schema.prisma中的Post和User模型,确保包含你在Pothos中暴露的所有字段。例如Post模型需对应:
model Post { id String @id @default(cuid()) visibleTo String published Boolean @default(false) hasImage Boolean @default(false) hasVideo Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt title String? content String? viewCount Int @default(0) author User @relation(fields: [authorId], references: [id]) authorId String likes Like[] comments Comment[] media Media[] category Category @relation(fields: [categoryId], references: [id]) categoryId String }
若模型缺失字段,更新后运行npx prisma generate重新生成Prisma Client,再重启服务。
3. Builder初始化配置错误
检查builder.ts的Prisma插件配置,确保传入正确的Prisma Client实例并初始化Query类型:
// api/graphql/builder.ts import SchemaBuilder from "@pothos/core"; import PrismaPlugin from "@pothos/plugin-prisma"; import type PrismaTypes from "@pothos/plugin-prisma/generated"; import prisma from "@/prisma/database"; export const builder = new SchemaBuilder<{ PrismaTypes: PrismaTypes; Context: {}; // 根据需求添加上下文类型 }>({ plugins: [PrismaPlugin], prisma: { client: prisma, }, }); // 必须初始化Query类型 builder.queryType({}); // 若需要Mutation,也需初始化 // builder.mutationType({});
未初始化Query/Mutation或插件配置错误,会导致字段无法被识别。
4. 缓存或热重载异常
NextJS热重载可能导致Schema构建异常,尝试:
- 停止开发服务器
- 删除
.next文件夹 - 重启开发服务器
5. 字段暴露方式错误
确认Pothos方法使用正确:
- 标量字段使用对应类型的
expose方法(如t.exposeString) - 关系字段的
t.relation参数需与Prisma模型中的关系名称完全一致
内容的提问来源于stack exchange,提问作者AnthonyDev220
相关产品推荐
相关产品推荐

