graphql / graphql/graphql-spec
Fields that do not return a value
- Dominant language
- JavaScript
- Stars
- 14.6k
- Forks
- 1.2k
- PR merge metrics
- No merged PRs in 30d
Description
### Motivation
Our application defines some mutations that are purely used to trigger side effects and don't return a value.
GraphQL enforces the definition of a return type for those fields. Due to this constraint and lack of a better alternative, I have found all of the following permutations to be present in our codebase:
- type `Boolean!`, resolver always returns `true`
- type `Boolean!`, resolver returns a boolean indicating success - swallowing errors!
- type `Boolean`, resolver is defined to return `void`, result is serialized to `null`
While this inconsistency is not pretty for someone on the server side, it is especially bad for the client. Depending on the quality of the schema documentation, they won't know for sure if the return type is meaningful.
### Idea
Introduce an idiomatic way to represent the notion of a field that returns no value.
### Possible Solutions
#### No Type
Allow defining the field with no return type at all.
```graphql
type Mutation {
fireAndForget
}
```
- terse definition
- affects the grammar of GraphQL, perhaps causes ambiguities (?)
- requires making `__Field.type` nullable in introspection
It is unclear to me how this field would be represented in the serialized result, given it is a map and there has to be *something* in the place of the value. Perhaps `null`?
#### void
Introduce a new keyword `void` that acts as a pseudo-type.
```graphql
type Mutation {
fireAndForget: void
}
```
- reserving a keyword might cause breakage
- more explicit than omission
#### Unit Type
Introduce a new type `Unit` that allows only one possible value and thus can hold no information.
```graphql
type Mutation {
fireAndForget: Unit
}
```
Some rules:
- `Unit` is implicitly non-nullable, otherwise the value could be `null` or whatever the representation of `Unit` is
- `Unit` can not be used in lists
Building upon existing types, I can see the definition of this type being either one of:
- a scalar with only a single allowed value - the string `UNIT`
- an enum with only a single value `UNIT`
I can see this type being useful as an argument too, enabling a binary toggle between not passing the argument at all or passing it.
Contributor guide
Assessment
This issue has not been assessed yet.