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:
- It always has exactly two
Int! values: start end endInclusive.
- The typical approach for a type with multiple properties would be to create a
type IntRange with two Int! fields for output, and an input 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-in Scalar type except String. The latter would require a custom serialization format like "start...endInclusive".
According to the spec Scalar represents primitive values.
The most basic type is a Scalar. A scalar represents a primitive value, like a string or an integer.
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:
GraphQL scalars are serialized according to the serialization format being used. There may be a most appropriate serialized primitive for each given scalar type, and the server should produce each primitive where appropriate.
So I can use a JSON object:
{ "start": 1, "endInclusive": 10 }
Input coercing for custom scalars isn't defined beyond the following:
If a GraphQL server expects a scalar type as input to an argument, coercion is observable and the rules must be well defined. If an input value does not match a coercion rule, a query error must be raised.
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 a scalar IntRange:
{ start: 1, endInclusive: 10 }
Conclusion
Something like IntRange could be seen as a primitive and thus be implemented as a Scalar. It could be represented using a JSON object for output and variable input, and as ObjectValue 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 Values are valid to use for a Scalar.
The spec makes no statement about what GraphQL input values are valid for a custom
Scalarvalue.Let's take an
IntRangetype for example:Int!values:startendendInclusive.type IntRangewith twoInt!fields for output, and aninput IntRangeInputwith the same two fields for input.That's unnecessary for such a simple type, so I'd love to represent it as a
Scalarinstead. But because the type comprised of two values it cannot be represented by any other built-inScalartype exceptString. The latter would require a custom serialization format like"start...endInclusive".According to the spec
Scalarrepresents primitive values.The spec doesn't really say what primitive means.
My idea is now to simply use a custom
Scalarwith 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:
{ "start": 1, "endInclusive": 10 }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
ObjectValueto represent ascalar IntRange:{ start: 1, endInclusive: 10 }Conclusion
Something like
IntRangecould 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 asObjectValuefor 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
Values are valid to use for aScalar.