What should be the GraphQL mutation return type when there is no data to return?

A field in GraphQL must always have a type. GraphQL has the concept of null but null is not itself a type -- it simply represents the lack of value.

There is no "void" type in GraphQL. However, types are nullable by default, so regardless of a field's type, your resolver can return nothing and the field will simply resolve to null. So you can just do

type Mutation {
  deleteQueue(input: QueueInput!): Boolean #or any other type
}

Or if you want a scalar that specifically represents null, you can create your own.

const { GraphQLScalarType } = require('graphql')

const Void = new GraphQLScalarType({
  description: 'Void custom scalar',
  name: 'Void',
  parseLiteral: (ast) => null,
  parseValue: (value) => null,
  serialize: (value) => null,
})

and then do

type Mutation {
  deleteQueue(input: QueueInput!): Void
}

That said, it's common practice to return something. For deletions, it's common to return either the deleted item or at least its ID. This helps with cache-management on the client side. It's also becoming more common to return some kind of mutation payload type to better encapsulate client errors.

There's any number of fields you could include on a "payload" type like this:

type Mutation {
  deleteQueue(input: QueueInput!): DeleteQueuePayload
}

type DeleteQueuePayload {
  # the id of the deleted queue
  queueId: ID

  # the queue itself
  queue: Queue

  # a status string
  status: String

  # or a status code
  status: Int

  # or even an enum
  status: Status

  # or just include the client error
  # with an appropriate code, internationalized message, etc.
  error: ClientError

  # or an array of errors, if you want to support validation, for example
  errors: [ClientError!]!
}

DeleteQueuePayload could even be a union of different types, enabling the client to use the __typename to determine the result of the mutation.

What information you expose, however, depend on your specific needs, and what specific pattern you employ is boils down to opinion.

See here and here for additional discussion and examples.


I use graphql server with prisma and when deleting something prisma return info about the something that did get deleted. That's good because when you preform the deletion from the client and get back a response about it that help you to make the ui change by updating the cache