TypeError with Pothos Graphql and prisma-plugin

242 views Asked by At

I am building a social app with nextjs for frontend and SSR, graphql-yoga server, and pothos for typesafe graphql and prisma for my db. I have followed all the example given in all their documentation for integration. However, I am getting a confusing error.

ERR Error: Type Post must define one or more fields.

Type User must define one or more fields.

and in my graphql yoga interface, I see this error message

"message": "Type Post must define one or more fields.\n\nType User must define one or more fields.",

In my type definition I clearly defined all fields in Post and User type, so I am very confused in which I do not know what this error is referring to.

Here is my folder structure for my app directory:

api
 ┣ auth
 ┃ ┗ [...nextauth]
 ┃ ┃ ┣ authorization.ts
 ┃ ┃ ┣ options.ts
 ┃ ┃ ┗ route.ts
 ┗ graphql
 ┃ ┣ types
 ┃ ┃ ┣ Post.ts
 ┃ ┃ ┣ Profile.ts
 ┃ ┃ ┗ User.ts
 ┃ ┣ builder.ts
 ┃ ┣ route.ts
 ┃ ┗ schema.ts

and here is my Post.ts folder:

//./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,
                },
            });
        },
    }),
}));

Here is my 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,
    // While using Next.js file convention for routing, we need to configure Yoga to use the correct endpoint
    graphqlEndpoint: "/api/graphql",

    // Yoga needs to know how to create a valid Next response
    fetchAPI: { Response: Response },
});

export {
    handleRequest as GET,
    handleRequest as POST,
    handleRequest as OPTIONS,
};
1

There are 1 answers

0
AnthonyDev220 On

Solve the problem by defining a root query type and root mutation type in my builder.ts file as below:

/* MUST DEFINE A ROOT QUERY TYPE AND root MUTATION TYPE WHEN USING POTHOS GRAPHQL */
builder.queryType({
    description: "The query root type.",
    fields: (t) => ({
        ok: t.boolean({ resolve: () => true }),
    }),
});
builder.mutationType({});

It is best practice to define it next to your schema builder for it to pick up.

//schema builder from @pothos/core
export const builder = new SchemaBuilder<{
    PrismaTypes: PrismaTypes;
    Context: {};
    Scalars: {
        DateTime: { Input: Date; Output: Date };
    };
}>({
    plugins: [PrismaPlugin],
    prisma: {
        client: prisma,
        filterConnectionTotalCount: true,
        onUnusedQuery: process.env.NODE_ENV === "production" ? null : "warn",
    },
});