Turning Non-null to is_null
Note: for support questions, please use stackoverflow. This repository's issues are reserved for feature requests and bug reports. Hey :) so I was reading docs, and then I remembered something: simple is better than complex.
Why would we create a new class and object type because we don't want nullable values? isn't accepting a nullable value a property? then maybe we could have used is_null=True/False, and it gives us more control, because now we can have 4 possibility:
- is required, but accept null
- is not required, but accept null
- is required, but null isn't acceptable
- is not required, but null isn't acceptable
-
What is the current behavior? Using a new class/object, to adopt a behaviour that can be achieved as property
-
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via a github repo, https://repl.it or similar.
-
What is the expected behavior? Having is_null, beside required.
-
What is the motivation / use case for changing the behavior? This gives us more flexible, and less complex scalars.
-
Please tell us about your environment:
- Version:
- Platform:
-
Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow)
I'd do the PR myself, but I wonder to see if that's something maintainers agree with me or not.
Graphql has a weird relationship with nullable field.
The nuance of "a required nullable field" is not achievable as far as I know in the schema definition... indeed the "no value" is null and is valid for optional fields too.
Meaning that
type Mutation {
doNothing(input: DoNothingInput!): DoNothingPayload
}
type DoNothingPayload {
nullableInt: Int
}
input DoNothingInput {
nullableInt: Int
}
that can be obtained with:
nullable_int = graphene.Int(required=False)
serves both purposes of being nullable and being optional.
Indeed you can do the following 3 behavior:
- you provide an actual integer input:
mutation {
doNothing(input: { nullableInt: 1 }) {
nullableInt
}
}
and in your resolver "nullable_int" in input is True (and input.nullable_int is 1 and input["nullable_int"] is 1 )
-
you can provide
nullinput:
mutation {
doNothing(input: { nullableInt: null }) {
nullableInt
}
}
and in your resolver "nullable_int" in input is True (and input.nullable_int is None and input["nullable_int"] is None )
- you can provide no input at all:
mutation {
doNothing(input: { }) {
nullableInt
}
}
and in your resolver "nullable_int" in input is False (and input.nullable_int is None and input["nullable_int"] actually fails)
So if you want to have a required nullable input, your only way to do it is to make the type required=False and add an assertion in your mutation
assert "nullable_int" in input
There is no way as far as I know to enforce that at schema level...
Note that this issue is an open conversation in the grapqh specs: https://github.com/graphql/graphql-spec/issues/476