diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 19256ba03..c6bac48d5 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -327,18 +327,14 @@ represent additional fields a GraphQL client only accesses locally. ScalarTypeDefinition : Description? scalar Name Directives[Const]? Scalar types represent primitive leaf values in a GraphQL type system. GraphQL -responses take the form of a hierarchical tree; the leaves on these trees are -GraphQL scalars. - -All GraphQL scalars are representable as strings, though depending on the -response format being used, there may be a more appropriate primitive for the -given scalar type, and server should use those types when appropriate. - -GraphQL provides a number of built-in scalars, but type systems can add -additional scalars with semantic meaning. For example, a GraphQL system could -define a scalar called `Time` which, while serialized as a string, promises to -conform to ISO-8601. When querying a field of type `Time`, you can then rely on -the ability to parse the result with an ISO-8601 parser and use a +responses take the form of a hierarchical tree; the leaves of this tree are +typically GraphQL Scalar types (but may also be Enum types or {null} values). + +GraphQL provides a number of built-in scalars (see below), but type systems can +add additional scalars with semantic meaning. For example, a GraphQL system +could define a scalar called `Time` which, while serialized as a string, +promises to conform to ISO-8601. When querying a field of type `Time`, you can +then rely on the ability to parse the result with an ISO-8601 parser and use a client-specific primitive for time. Another example of a potentially useful custom scalar is `Url`, which serializes as a string, but is guaranteed by the server to be a valid URL. @@ -348,27 +344,34 @@ scalar Time scalar Url ``` -A server may omit any of the built-in scalars from its schema, for example if a -schema does not refer to a floating-point number, then it may omit the -`Float` type. However, if a schema includes a type with the name of one of the -types described here, it must adhere to the behavior described. As an example, -a server must not include a type called `Int` and use it to represent -128-bit numbers, internationalization information, or anything other than what -is defined in this document. +**Built-in Scalars** + +GraphQL specifies a basic set of well-defined Scalar types: {Int}, {Float}, +{String}, {Boolean}, and {ID}. A GraphQL framework should support all of these +types, and a GraphQL service which provides a type by these names must adhere to +the behavior described for them in this document. As an example, a service must +not include a type called {Int} and use it to represent 64-bit numbers, +internationalization information, or anything other than what is defined in +this document. + +When returning the set of types from the `__Schema` introspection type, all +referenced built-in scalars must be included. If a built-in scalar type is not +referenced anywhere in a schema (there is no field, argument, or input field of +that type) then it must not be included. When representing a GraphQL schema using the type system definition language, -the built-in scalar types should be omitted for brevity. +all built-in scalars must be omitted for brevity. -**Result Coercion** +**Result Coercion and Serialization** A GraphQL server, when preparing a field of a given scalar type, must uphold the contract the scalar type describes, either by coercing the value or producing a field error if a value cannot be coerced or if coercion may result in data loss. A GraphQL service may decide to allow coercing different internal types to the -expected return type. For example when coercing a field of type `Int` a boolean -`true` value may produce `1` or a string value `"123"` may be parsed as base-10 -`123`. However if internal type coercion cannot be reasonably performed without +expected return type. For example when coercing a field of type {Int} a boolean +{true} value may produce {1} or a string value {"123"} may be parsed as base-10 +{123}. However if internal type coercion cannot be reasonably performed without losing information, then it must raise a field error. Since this coercion behavior is not observable to clients of the GraphQL server, @@ -376,6 +379,13 @@ the precise rules of coercion are left to the implementation. The only requirement is that the server must yield values which adhere to the expected Scalar type. +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. + +See [Serialization Format](#sec-Serialization-Format) for more detailed +information on the serialization of scalars in common JSON and other formats. + **Input Coercion** If a GraphQL server expects a scalar type as input to an argument, coercion @@ -394,12 +404,6 @@ input value. For all types below, with the exception of Non-Null, if the explicit value {null} is provided, then the result of input coercion is {null}. -**Built-in Scalars** - -GraphQL provides a basic set of well-defined Scalar types. A GraphQL server -should support all of these types, and a GraphQL server which provide a type by -these names must adhere to the behavior described below. - ### Int @@ -409,7 +413,7 @@ that type to represent this scalar. **Result Coercion** -Fields returning the type `Int` expect to encounter 32-bit integer +Fields returning the type {Int} expect to encounter 32-bit integer internal values. GraphQL servers may coerce non-integer internal values to integers when @@ -444,10 +448,10 @@ should use that type to represent this scalar. **Result Coercion** -Fields returning the type `Float` expect to encounter double-precision +Fields returning the type {Float} expect to encounter double-precision floating-point internal values. -GraphQL servers may coerce non-floating-point internal values to `Float` when +GraphQL servers may coerce non-floating-point internal values to {Float} when reasonable without losing information, otherwise they must raise a field error. Examples of this may include returning `1.0` for the integer number `1`, or `123.0` for the string `"123"`. @@ -471,9 +475,9 @@ and that representation must be used here. **Result Coercion** -Fields returning the type `String` expect to encounter UTF-8 string internal values. +Fields returning the type {String} expect to encounter UTF-8 string internal values. -GraphQL servers may coerce non-string raw values to `String` when reasonable +GraphQL servers may coerce non-string raw values to {String} when reasonable without losing information, otherwise they must raise a field error. Examples of this may include returning the string `"true"` for a boolean true value, or the string `"1"` for the integer `1`. @@ -493,9 +497,9 @@ representation of the integers `1` and `0`. **Result Coercion** -Fields returning the type `Boolean` expect to encounter boolean internal values. +Fields returning the type {Boolean} expect to encounter boolean internal values. -GraphQL servers may coerce non-boolean raw values to `Boolean` when reasonable +GraphQL servers may coerce non-boolean raw values to {Boolean} when reasonable without losing information, otherwise they must raise a field error. Examples of this may include returning `true` for non-zero numbers. @@ -509,8 +513,8 @@ other input values must raise a query error indicating an incorrect type. The ID scalar type represents a unique identifier, often used to refetch an object or as the key for a cache. The ID type is serialized in the same way as -a `String`; however, it is not intended to be human-readable. While it is -often numeric, it should always serialize as a `String`. +a {String}; however, it is not intended to be human-readable. While it is +often numeric, it should always serialize as a {String}. **Result Coercion** @@ -583,8 +587,8 @@ type Person { } ``` -Where `name` is a field that will yield a `String` value, and `age` is a field -that will yield an `Int` value, and `picture` is a field that will yield a +Where `name` is a field that will yield a {String} value, and `age` is a field +that will yield an {Int} value, and `picture` is a field that will yield a `Url` value. A query of an object value must select at least one field. This selection of @@ -1250,7 +1254,7 @@ EnumValuesDefinition : { EnumValueDefinition+ } EnumValueDefinition : Description? EnumValue Directives[Const]? -GraphQL Enum types, like scalar types, also represent leaf values in a GraphQL +GraphQL Enum types, like Scalar types, also represent leaf values in a GraphQL type system. However Enum types describe the set of possible values. Enums are not references for a numeric value, but are unique values in their own