pothos icon indicating copy to clipboard operation
pothos copied to clipboard

Drizzle integration.

Open RajaARK99 opened this issue 1 year ago • 20 comments

We need support drizzle integration.

RajaARK99 avatar Sep 13 '23 16:09 RajaARK99

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

hayes avatar Sep 13 '23 21:09 hayes

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

Enalmada avatar Sep 23 '23 00:09 Enalmada

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.

hayes avatar Sep 23 '23 01:09 hayes

@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

Enalmada avatar Sep 26 '23 01:09 Enalmada

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

liquiad avatar Sep 26 '23 23:09 liquiad

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();

arolson101 avatar May 11 '24 01:05 arolson101