You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 02:23:22