Pothos
Guide

Using args

Arguments let a client pass values to a field's resolver. They work on query, mutation, object, and interface fields. Define them in a field's args option and read them from the resolver's second parameter.

Scalars

Using the t.arg method

Use t.arg with a scalar type name:

import SchemaBuilder from '@pothos/core';

const builder = new SchemaBuilder({});

builder.queryType({
  fields: (t) => ({
    greeting: t.string({
      args: {
        name: t.arg({ type: 'String', required: true }),
      },
      resolve: (_parent, args) => `Hello, ${args.name}!`,
    }),
  }),
});

Using convenience methods

The equivalent shorthand for the argument above is t.arg.string({ required: true }). Other scalar helpers include t.arg.id, t.arg.int, t.arg.float, and t.arg.boolean. Each also has a list helper, such as t.arg.stringList.

Required args

Arguments are optional by default. Set required: true to reject omitted or null values. See Changing Default Nullability to change this default.

An optional argument can be omitted or explicitly set to null. A defaultValue applies when an argument is omitted; it does not replace an explicit null. The resolver below handles both:

builder.queryField('repeat', (t) =>
  t.string({
    args: {
      text: t.arg.string({ required: true }),
      times: t.arg.int({ defaultValue: 2 }),
    },
    resolve: (_parent, args) => args.text.repeat(Math.max(0, args.times ?? 1)),
  }),
);

Lists

Wrap a type in an array to create a list argument, or use a list helper:

builder.queryField('knownGiraffes', (t) =>
  t.stringList({
    args: {
      names: t.arg.stringList({ required: true }),
      moreNames: t.arg({ type: ['String'], required: true }),
    },
    resolve: (_parent, args) =>
      [...args.names, ...args.moreNames].filter((name) => ['Gina', 'James'].includes(name)),
  }),
);

List items are non-null by default, even when the list argument is optional. Use separate list and items settings to allow null entries in a required list:

builder.queryField('nonNullNames', (t) =>
  t.stringList({
    args: {
      names: t.arg.stringList({
        required: { list: true, items: false },
      }),
    },
    resolve: (_parent, args) => args.names.filter((name) => name != null),
  }),
);

Other types

Arguments can also use enums and input objects. Output objects, interfaces, and unions cannot be argument types.

This object field accepts an enum argument to choose the unit for its result:

const LengthUnit = builder.enumType('LengthUnit', {
  values: { Feet: {}, Meters: {} },
});

const GiraffeRef = builder.objectRef<{ heightInMeters: number }>('Giraffe').implement({
  fields: (t) => ({
    height: t.float({
      args: {
        unit: t.arg({ type: LengthUnit, defaultValue: 'Meters' }),
      },
      resolve: (giraffe, args) =>
        args.unit === 'Feet' ? giraffe.heightInMeters * 3.281 : giraffe.heightInMeters,
    }),
  }),
});

builder.queryField('giraffe', (t) =>
  t.field({
    type: GiraffeRef,
    resolve: () => ({ heightInMeters: 5 }),
  }),
);

Nested Lists

Use t.arg.listRef to nest lists. Its required option controls the items of that list; required on t.arg controls whether the outermost list can be omitted or null.

builder.queryField('countNames', (t) =>
  t.int({
    args: {
      groups: t.arg({
        type: t.arg.listRef(t.arg.listRef('String', { required: false })),
        required: true,
      }),
    },
    resolve: (_parent, args) =>
      args.groups.reduce(
        (count, group) => count + group.filter((name) => name != null).length,
        0,
      ),
  }),
);

export const schema = builder.toSchema();

Here, groups has GraphQL type [[String]!]!: the outer list and each inner list are required, but strings inside the inner lists can be null. Without { required: false }, those strings would also be non-null.

Querying with arguments

The examples above form one schema. This query exercises required arguments, defaults, lists, and the enum argument on an object field:

query {
  greeting(name: "Gina")
  repeat(text: "ha")
  once: repeat(text: "ha", times: null)
  knownGiraffes(names: ["Gina", "Unknown"], moreNames: ["James"])
  nonNullNames(names: ["Gina", null, "James"])
  giraffe {
    meters: height
    feet: height(unit: Feet)
  }
  countNames(groups: [["Gina", null], ["James"]])
}
{
  "data": {
    "greeting": "Hello, Gina!",
    "repeat": "haha",
    "once": "ha",
    "knownGiraffes": ["Gina", "James"],
    "nonNullNames": ["Gina", "James"],
    "giraffe": { "meters": 5, "feet": 16.405 },
    "countNames": 2
  }
}

On this page