I have several GraphQL queries and mutations, now I’m trying to implement a delete mutation without returning any data:
type Mutation{
addElement(element: ElementData): ID
removeElement(id: ID): ┬┐?
}
However, it seems to be required to have a return value for the delete operation. Is there a way to perform an “empty” response in GraphQL? I would like to avoid things like returning a boolean or status flag if possible.
I’m not sure on what are the best practices for GraphQL delete operations.
4 Answers
Reset to default
According to this Github issue you cannot return nothing.
You can define a return type which is nullable e.g.
type Mutation {
addElement(element: ElementData): ID
removeElement(id: ID): Boolean
}
But I suggest you return the id of the deleted element, because if you want to work with a cached store you have to update the store when the delete mutation has ran successfully.
2
-
29
In case of deletion you are better off returning the product ID, as suggested (since it’s graphql, perhaps even the whole product). However, some operations truly require no data. For those cases one could define
type Void
and then dosomeOperation(input: InputObject!): Void
to indicate the intent clearly.– AviusOct 15, 2018 at 15:20
-
1
An example of a mutation that needs to return value is a logout, which would just destroy the session.
– SandyApr 2, 2022 at 9:28
(A) Solution with graphql-scalars
The original answer is below.
Here is another one solution with graphql-scalars
library:
- install
npm install graphql-scalars
and then - import their
Void
type: https://www.graphql-scalars.dev/docs/scalars/void
(B) Solution with a custom scalar
Note: design with
void
-result from mutations goes against “GQL best practices”
This example was written for NodeJS Apollo Framework, but it is pretty easy to convert the implementation for your language/framework
I’m pretty sure: there is an NPM-package named graphql-void
but if you don’t want to add another one dependency just copy this code.
1. define Void
-scalar in your schema
# file: ./schema.gql
scalar Void
2. implement resolver
// file ./scalar-void.js
import { GraphQLScalarType } from 'graphql'
const Void = new GraphQLScalarType({
name: 'Void',
description: 'Represents NULL values',
serialize() {
return null
},
parseValue() {
return null
},
parseLiteral() {
return null
}
})
export Void
3. add the resolver to ApolloServer
Add the Void
resolver to the options of your instance of Apollo Server:
# file: ./server.js
import { ApolloServer } from 'apollo-server-express'
import { Void } from './scalar-void'
const server = new ApolloServer({
typeDefs, // use your schema
resolvers: {
Void: Void,
// ... your resolvers
},
})
4. use Void
for your mutations in the schema
Finally, use the new scalar
in your schema:
# file: ./schema.gql
type Mutation{
addElement(element: ElementData): ID
removeElement(id: ID): Void
}
2
-
8
What part of the linked “GQL best practices” do you suggest is saying that a void-returning mutation is bad practise? I was unable to find any such recommendation.
– MEMarkSep 28, 2020 at 9:04
-
1
@MEMark graphql-rules.com/rules/mutation-payload : “Every mutation should have a unique payload type” . and I’m going to update the link in the answer
– maxkoryukovJul 22, 2021 at 18:21
If you use TypeScript and graphql-codegen
:
- In the GraphQL schema:
scalar Void type Mutation { removeElement(id: ID): Void }
- In the codegen config for resolvers:
config: scalars: Void: "void"
With this config TypeScript will ensure that nothing is returned from the removeElement
mutation resolver. And the returning value for the mutation will always be null
on the GraphQL side.
Check out graphql-scalars Void. This is standard boilerplate for all of my GraphQL projects.
npm i graphql-scalars
Not the answer you’re looking for? Browse other questions tagged
or ask your own question.
or ask your own question.
|