hayes / pothos

Pothos GraphQL is library for creating GraphQL schemas in typescript using a strongly typed code first approach
https://pothos-graphql.dev
ISC License
2.28k stars 153 forks source link

Drizzle integration. #1027

Open RajaARK99 opened 9 months ago

RajaARK99 commented 9 months ago

We need support drizzle integration.

hayes commented 9 months ago

There is some initial experimentation around this here: https://github.com/hayes/pothos/pull/1028 but you can always just use drizzle manually, you don't need a plugin to use drizzle

Enalmada commented 9 months ago

@hayes thanks so much for the time you put into pothos. I just moved to Pothos and Drizzle and was really happy how easy builder.objectRef made things. Awesome there might be even tighter integration one day but it certainly is very nice even as it is.

// @/server/db/schema
export const UserTable = pgTable('user', {
    id: serial('id').primaryKey(),
   ....
});

export type User = InferSelectModel<typeof UserTable>;
export type UserInput = InferInsertModel<typeof UserTable>;
// user.model.ts
import { type User } from '@/server/db/schema';
import { builder } from '@/server/graphql/builder';

export const UserType = builder.objectRef<User>('User');

UserType.implement({
  fields: (t) => ({
    id: t.exposeID('id'),
    ...
  }),
});

builder.queryField('me', (t) =>
  t.field({
    type: UserType,
    nullable: true,
    resolve: (root, args, ctx) => {
      return new UserService().me(ctx);
    },
  })
);
hayes commented 9 months ago

Nice, glad it's working well for you! If you've got any advanced cases where you are doing joins/dataloading/nested selects or anything like that, id be curious to see how you're doing it or what the pain points there are.

The current plan with the drizzle plugin is to lean on a combination of drizzles relational query builder, and data-loaders similar to what Prisma does. This kinda gets away from being close to SQL which is one of the things that makes drizzle interesting, but it's a lot easier to build out that way.

Enalmada commented 9 months ago

@hayes I am currently only using it in simple cases but happy to share what I am doing. Here are some helpers I am currently prototyping which make it more prisma like and make the service code a bit cleaner when dealing with things like pagination: https://github.com/Enalmada/drizzle-helpers

Here is a demo project where this can be seen in action: https://github.com/Enalmada/nextjs-boilerplate

liquiad commented 9 months ago

I would love to see the Drizzle plugin make it out. Prisma leaves a lot to be desired regarding performance. N+1 queries with Prisma will add exponentially more round trips to your database, which is a problem Drizzle simply doesn't have. Properly transforming a GraphQL query's relations to left joins in a single SQL statement is the dream.

As of 10/14/23, Prisma is part of the way there now lol https://github.com/prisma/prisma/releases/tag/5.4.0

arolson101 commented 1 month ago

FWIW, I got it working using drizzle-graphql and AddGraphQLPlugin

import { buildSchema } from 'drizzle-graphql';
import AddGraphQLPlugin from '@pothos/plugin-add-graphql';

const conn = postgres(env.DATABASE_URL);
const db = drizzle(conn, { schema });
const { entities } = buildSchema(db);

const builder = new SchemaBuilder({
  plugins: [AddGraphQLPlugin],
});

const User = builder.addGraphQLObject(entities.types.UsersItem, {
  name: 'User',
  description: 'description for User',
  fields: (t) => ({
    id: t.exposeID('id'),
  }),
});

const UserUpdate = builder.addGraphQLObject(entities.types.UsersSelectItem, {
  name: 'UserUpdate',
  fields: (t) => ({
    id: null,
  }),
});

builder.queryType({
  fields: (t) => ({
    users: t.field({
      type: [User],
      resolve: async (_root, _args, { db }) => {
        const users = await db.query.users.findMany();
        return users;
      },
    }),
  }),
});

export const schema = builder.toSchema();