Pothos

Drizzle Objects

Defining Objects

The builder.drizzleObject method can be used to define GraphQL Object types based on a drizzle table:

const UserRef = builder.drizzleObject('users', {
  name: 'User',
  fields: (t) => ({
    firstName: t.exposeString('firstName'),
    lastName: t.exposeString('lastName'),
  }),
});

You will be able to "expose" any column in the table, and GraphQL fields do not need to match the names of the columns in your database. The returned UserRef can be used like any other ObjectRef in Pothos.

Custom fields

You will often want to define fields in your API that do not correspond to a specific database column. To do this, you can define fields with a resolver like any other Pothos object type:

const UserRef = builder.drizzleObject('users', {
  name: 'User',
  fields: (t) => ({
    fullName: t.string({
      resolve: (user, args, ctx, info) => `${user.firstName} ${user.lastName}`,
    }),
  }),
});

Drizzle Fields

Drizzle objects and relations allow you to define parts of your schema backed by your drizzle schema, but don't provide a clear entry point into this Graph of data. To make your drizzle objects queryable, we will need to add fields that return our drizzle objects. This can be done using the t.drizzleField method. This can be used to define fields on the root Query type, or any other object type in your schema:

builder.queryType({
  fields: (t) => ({
    post: t.drizzleField({
      type: 'posts',
      args: {
        id: t.arg.id({ required: true }),
      },
      resolve: (query, root, args, ctx) =>
        db.query.posts.findFirst(
          query({
            where: {
              id: Number.parseInt(args.id, 10),
            },
          }),
        ),
    }),
    posts: t.drizzleField({
      type: ['posts'],
      resolve: (query, root, args, ctx) => db.query.posts.findMany(query()),
    }),
  }),
});

The resolve function of a drizzleField will be passed a query function that MUST be called and passed to a drizzle findOne or findMany query. The query function optionally accepts any arguments that are normally passed into the query, and will merge these options with the selection used to resolve data for the nested GraphQL selections.

drizzleFieldWithInput

With the with-input plugin, t.drizzleFieldWithInput combines t.drizzleField with t.fieldWithInput. The input fields become an input object argument, and the resolver still receives the query function as its first argument:

builder.queryFields((t) => ({
  user: t.drizzleFieldWithInput({
    type: 'users',
    input: {
      id: t.input.id({ required: true }),
    },
    resolve: (query, root, args, ctx) =>
      db.query.users.findFirst(query({ where: { id: Number.parseInt(args.input.id, 10) } })),
  }),
}));

On this page