-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Clarify allowed Values for Scalar types #688
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@fluidsonic it is definitely allowed and custom scalars for JSON like structures do exactly this: they accept an input object AST as input element. But it could be more clear that arbitrary AST elements are accepted, yes. Have a look at this blog which fills in some details where the spec is not so clear (yet). |
Thanks @andimarek. Happy to hear that all are supported and that the spec (will) become clearer here in the future. At least the rule Input Object Field Names should be improved earlier. If applied strictly as specified it wouldn't allow an object value for scalars:
In (4) inputFieldDefinition cannot exist for a scalar type as it doesn't have field definitions. |
@fluidsonic The fact is that Input Object and Scalar are two different things. See this - https://spec.graphql.org/draft/#IsInputType():
That is, IMO it is a mistake to extend the effect of the validation rule you quoted above to scalars. But these are my assumptions. I am starting to interpret the specification. Saying it explicitly in the specification itself would certainly be better. |
@sungam3r the rule name "Input Object Field Names" is misleading in the spec. The validation actually validates (Input) Object Value Field Names. I'm not suggesting to extend the validation to Scalars. The spec is also inconsistent with name naming between "Object Value" and "Input Object Value". They both seem to refer to the same thing. |
I agree that something in the terminology is definitely worth changing. |
The spec states that:
(Source: http://spec.graphql.org/draft/#sel-DAPJDLAAENBAAvtE) I would say that's clear enough. For JSON as a serialization format that translates to "Whatever can be represented in JSON". |
@conradreuter serialization only covers variables (input) and response serialization (output). It does not state what kinds of GraphQL values are allowed as scalar values, nor does it solve the conflict with the input object value validation rule. |
@fluidsonic about your previous remark about the "Input Object Field Names" rule: this rules applies only to Input Object types not to all Input Object Asts (Literal) For example: scalar HelloWorldScalar
type Query {
echo(arg: HelloWorldScalar) String
} and a query: {echo(arg: {hello: "world"}) } This rule never applies because the AST To make it a bit more complex: scalar HelloWorldScalar
input ComplexArg {
customScalar: HelloWorldScalar
}
type Query {
echo(arg: ComplexArg) String
} and a query: {echo(arg: {customScalar: {hello: "world"}}) } Here the rule applies for I hope that helps. |
@andimarek I agree that the rule may be intended to mean just that.
If I follow that rule as written, |
@fluidsonic you are right, this could be improved. Have a look how it is implemented in GraphQL.js: https://github.com/graphql/graphql-js/blob/master/src/validation/rules/ValuesOfCorrectTypeRule.js#L47 Maybe you want to submit a clarification to the spec? That would be great! |
I think it's also worth noting that some widely adopted GraphQL paradigms are making use of this ambiguity already e.g. Apollo Federation spec makes use of an |
The spec makes no statement about what GraphQL input values are valid for a custom
Scalar
value.Let's take an
IntRange
type for example:Int!
values:start
endendInclusive
.type IntRange
with twoInt!
fields for output, and aninput IntRangeInput
with the same two fields for input.That's unnecessary for such a simple type, so I'd love to represent it as a
Scalar
instead. But because the type comprised of two values it cannot be represented by any other built-inScalar
type exceptString
. The latter would require a custom serialization format like"start...endInclusive"
.According to the spec
Scalar
represents primitive values.The spec doesn't really say what primitive means.
My idea is now to simply use a custom
Scalar
with an object representation for input and output.Output it's simple because the spec basically allows any format:
So I can use a JSON object:
Input coercing for custom scalars isn't defined beyond the following:
Basically the server can accept any value it wants to as long as it clearly defines that. That theoretically allows for using an
ObjectValue
to represent ascalar IntRange
:Conclusion
Something like
IntRange
could be seen as a primitive and thus be implemented as aScalar
. It could be represented using a JSON object for output and variable input, and asObjectValue
for input in a GraphQL document.However in the spec it is not clear whether that is acceptable or not.
Theoretically that approach can collide with the Input Object Field Names validation.
I suggest to clearly define what
Value
s are valid to use for aScalar
.The text was updated successfully, but these errors were encountered: