Optional Undefined Arguments
In the GraphQL world, input types can be optional which means that the client can either:
- Not specify a value at all
- Send null explicitly
- Send a non-null value
This is in contrast with the JVM world where objects can either have some specific value or don't have any value (i.e.
are null). As a result, when using default serialization logic it is not possible to distinguish between missing/unspecified
value and explicit null value.
Using OptionalInput wrapper
OptionalInput is a convenient sealed class wrapper that provides distinction between undefined, null, and non-null
values. If the argument is not specified in the request it will be represented as a OptionalInput.Undefined object, otherwise the
value will be wrapped in OptionalInput.Defined class. As a best practice, we highly recommend to set appropriate
default values to all optional arguments.
fun optionalInput(input: OptionalInput<String> = OptionalInput.Undefined): String = when (input) {
is OptionalInput.Undefined -> "input was not specified"
is OptionalInput.Defined<String> -> "input value: ${input.value}"
}
query OptionalInputQuery {
undefined: optionalInput # input was not specified
null: optionalInput(value: null) # input value: null
foo: optionalInput(value: "foo") # input value: foo
}
Regardless whether the generic type of OptionalInput is specified as nullable or not it will always result in a nullable
value in Defined class, i.e. OptionalInput<String> will appear as nullable String in the GraphQL schema and in the wrapped value.