Pothos v4 is now available! 🎉Check out the full migration guide here

Pothos

Queries, Mutations and Subscriptions

There are a few different ways to add queries to your schema. The simplest way is to define a Query type with your query fields using the builder.queryType() method.

builder.queryType({
  fields: (t) => ({
    // Add query for a simple scalar type
    hello: t.string({
      resolve: () => 'hello, world!',
    }),
    // Add a query for an object type
    giraffe: t.field({
      type: Giraffe,
      resolve: () => ({
        name: 'James',
      }),
    }),
    // Add a query for a list of objects
    giraffes: t.field({
      type: [Giraffe],
      resolve: () => [
        {
          name: 'James',
        },
      ],
    }),
  }),
});
 
const Giraffe = builder.objectRef<{ name: string }>('Giraffe');
 
Giraffe.implement({
  fields: (t) => ({
    name: t.exposeString('name'),
  }),
});

You can only use builder.queryType() once in your schema, because it is responsible for defining the Query type itself. If you want to split up your queries and add query fields individually, you can use the builder.queryField() method to add individual query fields to the Query type.

// You will still need to define the `Query` type somewhere in your schema to add individual query fields
builder.queryType({});
 
builder.queryField('hello', (t) =>
  t.string({
    resolve: () => 'hello, world!',
  }),
);
 
builder.queryField('giraffe', (t) =>
  t.field({
    type: Giraffe,
    resolve: () => ({
      name: 'James',
    }),
  }),
);

If you want to add multiple query fields at once, you can use the builder.queryFields() method.

builder.queryFields((t) => ({
  hello: t.string({
    resolve: () => 'hello, world!',
  }),
  giraffe: t.field({
    type: Giraffe,
    resolve: () => ({
      name: 'James',
    }),
  }),
}));

Mutations

Mutations work just like queries, and you can use the builder.mutationType(), builder.mutationField(), and builder.mutationFields() methods to add mutations to your schema.

builder.mutationType({
  fields: (t) => ({
    // Add mutation that returns a simple boolean
    post: t.boolean({
      args: {
        message: t.arg.string(),
      },
      resolve: async (root, args) => {
        // Do something with the message
        const success = await messageClient.postMessage(args.message);
 
        return success;
      },
    }),
  }),
});
 
builder.mutationField('createGiraffe', (t) =>
  t.field({
    type: Giraffe,
    args: {
      name: t.arg.string(),
    },
    resolve: async (root, args) => {
      const giraffe = {
        name: args.name,
      };
 
      await db.giraffes.create(giraffe);
 
      return giraffe;
    },
  }),
);

Subscriptions

Subscriptions too work just like queries and mutations where you can use the builder.subscriptionType(), builder.subscriptionField(), and builder.subscriptionFields() methods to add subscriptions to your schema.

builder.mutationType({
  fields: (t) => ({
    incrementCount: t.int({
      resolve: (_parent, _args, ctx) => {
        ctx.count.value += 1;
        ctx.pubSub.publish('COUNT_INCREMENT', ctx.count.value);
        return ctx.count.value;
      },
    }),
  }),
});
 
builder.subscriptionType({
  fields: (t) => ({
    incrementedCount: t.int({
      subscribe: (_parent, _args, ctx) => ctx.pubSub.subscribe('COUNT_INCREMENT'),
      resolve: (count) => count,
    }),
  }),
});

On this page