174 lines
5.7 KiB
Plaintext
174 lines
5.7 KiB
Plaintext
---
|
|
title: Adding your own Queries and Mutations
|
|
label: Custom Queries and Mutations
|
|
order: 20
|
|
desc: Payload allows you to add your own GraphQL queries and mutations, simply set up GraphQL in your main Payload Config by following these instructions.
|
|
keywords: graphql, resolvers, mutations, custom, queries, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
|
---
|
|
|
|
You can add your own GraphQL queries and mutations to Payload, making use of all the types that Payload has defined for you.
|
|
|
|
To do so, add your queries and mutations to the main Payload Config as follows:
|
|
|
|
| Config Path | Description |
|
|
| ------------------- | --------------------------------------------------------------------------- |
|
|
| `graphQL.queries` | Function that returns an object containing keys to custom GraphQL queries |
|
|
| `graphQL.mutations` | Function that returns an object containing keys to custom GraphQL mutations |
|
|
|
|
The above properties each receive a function that is defined with the following arguments:
|
|
|
|
**`GraphQL`**
|
|
|
|
This is Payload's GraphQL dependency. You should not install your own copy of GraphQL as a dependency due to underlying restrictions based on how GraphQL works. Instead, you can use the Payload-provided copy via this argument.
|
|
|
|
**`payload`**
|
|
|
|
This is a copy of the currently running Payload instance, which provides you with existing GraphQL types for all of your Collections and Globals - among other things.
|
|
|
|
## Return value
|
|
|
|
Both `graphQL.queries` and `graphQL.mutations` functions should return an object with properties equal to your newly written GraphQL queries and mutations.
|
|
|
|
## Example
|
|
|
|
`payload.config.js`:
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload'
|
|
import myCustomQueryResolver from './graphQL/resolvers/myCustomQueryResolver'
|
|
|
|
export default buildConfig({
|
|
graphQL: {
|
|
// highlight-start
|
|
queries: (GraphQL, payload) => {
|
|
return {
|
|
MyCustomQuery: {
|
|
type: new GraphQL.GraphQLObjectType({
|
|
name: 'MyCustomQuery',
|
|
fields: {
|
|
text: {
|
|
type: GraphQL.GraphQLString,
|
|
},
|
|
someNumberField: {
|
|
type: GraphQL.GraphQLFloat,
|
|
},
|
|
},
|
|
}),
|
|
args: {
|
|
argNameHere: {
|
|
type: new GraphQL.GraphQLNonNull(GraphQLString),
|
|
},
|
|
},
|
|
resolve: myCustomQueryResolver,
|
|
},
|
|
}
|
|
},
|
|
// highlight-end
|
|
},
|
|
})
|
|
```
|
|
|
|
## Resolver function
|
|
|
|
In your resolver, make sure you set `depth: 0` if you're returning data directly from the local API so that GraphQL can correctly resolve queries to nested values such as relationship data.
|
|
|
|
Your function will receive four arguments you can make use of:
|
|
|
|
Example
|
|
|
|
```ts
|
|
;async (obj, args, context, info) => {}
|
|
```
|
|
|
|
**`obj`**
|
|
|
|
The previous object. Not very often used and usually discarded.
|
|
|
|
**`args`**
|
|
|
|
The available arguments from your query or mutation will be available to you here, these must be configured via the custom operation first.
|
|
|
|
**`context`**
|
|
|
|
An object containing the `req` and `res` objects that will provide you with the `payload`, `user` instances and more, like any other Payload API handler.
|
|
|
|
**`info`**
|
|
|
|
Contextual information about the currently running GraphQL operation. You can get schema information from this as well as contextual information about where this resolver function is being run.
|
|
|
|
## Types
|
|
|
|
We've exposed a few types and utilities to help you extend the API further. Payload uses the GraphQL.js package for which you can view the full list of available types in the [official documentation](https://graphql.org/graphql-js/type/).
|
|
|
|
**`GraphQLJSON`** & **`GraphQLJSONObject`**
|
|
|
|
```ts
|
|
import { GraphQLJSON, GraphQLJSONObject } from '@payloadcms/graphql/types'
|
|
```
|
|
|
|
**`GraphQL`**
|
|
|
|
You can directly import the GraphQL package used by Payload, most useful for typing.
|
|
|
|
```ts
|
|
import { GraphQL } from '@payloadcms/graphql/types'
|
|
```
|
|
|
|
<Banner type="warning">
|
|
For queries, mutations and handlers make sure you use the `GraphQL` and `payload` instances provided via arguments.
|
|
</Banner>
|
|
|
|
|
|
**`buildPaginatedListType`**
|
|
|
|
This is a utility function that allows you to build a new GraphQL type for a paginated result similar to the Payload's generated schema.
|
|
It takes in two arguments, the first for the name of this new schema type and the second for the GraphQL type to be used in the docs parameter.
|
|
|
|
Example
|
|
|
|
```ts
|
|
import { buildPaginatedListType } from '@payloadcms/graphql/types'
|
|
|
|
export const getMyPosts = (GraphQL, payload) => {
|
|
return {
|
|
args: {},
|
|
resolve: Resolver,
|
|
// The name of your new type has to be unique
|
|
type: buildPaginatedListType('AuthorPosts', payload.collections['posts'].graphQL?.type),
|
|
}
|
|
}
|
|
```
|
|
|
|
**`payload.collections.slug.graphQL`**
|
|
|
|
If you want to extend more of the provided API then the `graphQL` object on your collection slug will contain additional types to help you re-use code for types, mutations and queries.
|
|
|
|
```ts
|
|
graphQL?: {
|
|
type: GraphQLObjectType
|
|
paginatedType: GraphQLObjectType
|
|
JWT: GraphQLObjectType
|
|
versionType: GraphQLObjectType
|
|
whereInputType: GraphQLInputObjectType
|
|
mutationInputType: GraphQLNonNull<any>
|
|
updateMutationInputType: GraphQLNonNull<any>
|
|
}
|
|
```
|
|
|
|
## Best practices
|
|
|
|
There are a few ways to structure your code, we recommend using a dedicated `graphql` directory so you can keep all of your logic in one place. You have total freedom of how you want to structure this but a common pattern is to group functions by type and with their resolver.
|
|
|
|
Example
|
|
|
|
```
|
|
src/graphql
|
|
---- queries/
|
|
index.ts
|
|
-- myCustomQuery/
|
|
index.ts
|
|
resolver.ts
|
|
|
|
---- mutations/
|
|
```
|