Skip to content

Clarify allowed Values for Scalar types #688

@fluidsonic

Description

@fluidsonic

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    🤷‍♀️ AmbiguityAn issue/PR which identifies or fixes spec ambiguity

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions