rmosolgo/graphql-ruby

Rationale for the "defaultValueInvalidOnNonNullVariable" validation

BoD opened this issue ยท 2 comments

BoD commented

It looks like a query like this:

query MyQuery($first: Int! = 10) { ... }

is being rejected with Non-null variable $first can't have a default value.

It looks like this is implemented here.

Any insight as why this is disallowed? I can't seem to find anything in in the GraphQL spec about it, and graphql-js seems to allow it.

I can confirm that my understanding of the spec suggests this:

query MyQuery($skip: Boolean! = true) {
  __typename @skip(if: $skip)
}

is a valid query for any GraphQL schema, even with no variables provided.

CoerceVariableValues in the spec details what happens when there's a default value but no supplied value:

3.g. If hasValue is not true and defaultValue exists (including null):
3.g.i. Add an entry to coercedValues named variableName with the value defaultValue.

As far as I am aware, there is no rule in the spec forbidding a defaultValue on a non-null variable, nor on arguments nor on input fields. These positions are "required" if they are a non-nullable type and they have no default. Giving them a default makes them "optional" (they're also optional if they are nullable).

Note to self on `= null` default

Note to self: having = null is not permitted due to the Values of Correct Type rule; namely:

Literal values must be compatible with the type expected in the position they are found as per the coercion rules defined in the Type System chapter.

See https://github.com/graphql/graphql-spec/pull/793/files#diff-0f02d73330245629f776bb875e5ca2b30978a716732abca136afdd028d5cd33c for related PR that I really should get back around to.

Hey, thanks for asking. It was probably mistakenly added a long time ago ๐Ÿ™ˆ . I bet nobody has reported the problem since it can be worked around by removing the !.

Thanks for linking the relevant spec, @benjie -- I agree, removing it sounds like the right way forward.