---
title: "GraphQL — Custom Queries and Mutations"
aliases: [graphql-custom-resolvers, extending-graphql]
tags: [payloadcms, graphql, queries, mutations, resolvers]
sources: [raw/graphql__extending.md]
created: 2026-05-15
updated: 2026-05-15
---

## Overview

Payload exposes two config keys for adding custom GraphQL operations, both receiving `(GraphQL, payload)` as arguments:

| Config Path | Description |
|-------------|-------------|
| `graphQL.queries` | Function returning object of custom query definitions |
| `graphQL.mutations` | Function returning object of custom mutation definitions |

**Critical:** use the `GraphQL` and `payload` instances provided via arguments — never install your own `graphql` package alongside Payload.

## Defining Custom Operations

```ts
import { buildConfig } from 'payload'
import myCustomQueryResolver from './graphql/queries/myCustomQuery/resolver'

export default buildConfig({
  graphQL: {
    queries: (GraphQL, payload) => ({
      MyCustomQuery: {
        type: new GraphQL.GraphQLObjectType({
          name: 'MyCustomQuery',
          fields: {
            text: { type: GraphQL.GraphQLString },
            someNumberField: { type: GraphQL.GraphQLFloat },
          },
        }),
        args: {
          argNameHere: {
            type: new GraphQL.GraphQLNonNull(GraphQL.GraphQLString),
          },
        },
        resolve: myCustomQueryResolver,
      },
    }),
  },
})
```

## Resolver Function

Resolvers receive four arguments:

```ts
async (obj, args, context, info) => {}
```

| Arg | Description |
|-----|-------------|
| `obj` | Previous object — rarely used, usually discarded |
| `args` | Query/mutation arguments (must be declared in the operation first) |
| `context` | `{ req, res }` — gives access to `payload`, `user`, and other request state |
| `info` | Schema info + contextual data about the running operation |

**Gotcha:** set `depth: 0` when returning data directly from the Local API so GraphQL can correctly resolve nested relationship values.

## Useful Types & Utilities

```ts
import { GraphQLJSON, GraphQLJSONObject } from '@payloadcms/graphql/types'
import { GraphQL } from '@payloadcms/graphql/types'
import { buildPaginatedListType } from '@payloadcms/graphql/types'
```

### `buildPaginatedListType`

Creates a paginated result type matching Payload's generated schema:

```ts
type: buildPaginatedListType(
  'AuthorPosts',                              // must be unique
  payload.collections['posts'].graphQL?.type, // GraphQL type for items
)
```

### `payload.collections[slug].graphQL`

Access auto-generated types per collection:

```ts
graphQL?: {
  type: GraphQLObjectType
  paginatedType: GraphQLObjectType
  JWT: GraphQLObjectType
  versionType: GraphQLObjectType
  whereInputType: GraphQLInputObjectType
  mutationInputType: GraphQLNonNull<any>
  updateMutationInputType: GraphQLNonNull<any>
}
```

## Recommended File Structure

```
src/graphql/
  queries/
    index.ts
    myCustomQuery/
      index.ts
      resolver.ts
  mutations/
```

## Key Takeaways

- Add custom ops via `graphQL.queries` / `graphQL.mutations` in `buildConfig` — both are functions receiving `(GraphQL, payload)`.
- Never install `graphql` independently — use the provided `GraphQL` argument to avoid version conflicts.
- Resolver signature: `(obj, args, context, info)` — `context.req` carries `payload` and `user`.
- Use `depth: 0` in Local API calls inside resolvers to avoid double-population.
- Re-use Payload's auto-generated types via `payload.collections[slug].graphQL` — avoids type duplication.
- `buildPaginatedListType` produces a Payload-compatible paginated response type.
- Group all custom GraphQL logic under `src/graphql/` — queries and mutations in separate sub-folders.

## Related

- [[wiki/payloadcms/rest-api|REST API]] — custom endpoints via `endpoints` array
- [[wiki/payloadcms/local-api|Local API]] — `payload.*` calls usable inside resolvers
- [[wiki/payloadcms/hooks|Hooks]] — alternative extension point for business logic
- [[wiki/payloadcms/configuration|Payload Config Overview]] — full `buildConfig` reference

---

*Source: raw/graphql__extending.md — https://payloadcms.com/docs/graphql/extending*
