diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 611b190b2..7d5ac6100 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -241,7 +241,7 @@ While Scalar types describe the leaf values of these hierarchical queries, Objec describe the intermediate levels. GraphQL Objects represent a list of named fields, each of which yield a value of -a specific type. Object values are serialized as ordered maps, where the +a specific type. Object values should be serialized as ordered maps, where the queried field names (or aliases) are the keys and the result of evaluating the field is the value, ordered by the order in which they appear in the query. @@ -261,8 +261,9 @@ that will yield an `Int` value, and `picture` is a field that will yield a A query of an object value must select at least one field. This selection of fields will yield an ordered map containing exactly the subset of the object -queried, in the order in which they were queried. Only fields that are declared -on the object type may validly be queried on that object. +queried, which should be represented in the order in which they were queried. +Only fields that are declared on the object type may validly be queried on +that object. For example, selecting all the fields of `Person`: @@ -357,9 +358,14 @@ excluding fragments for which the type does not apply and fields or fragments that are skipped via `@skip` or `@include` directives. This ordering is correctly produced when using the {CollectFields()} algorithm. -Response formats which support ordered maps (such as JSON) must maintain this -ordering. Response formats which do not support ordered maps may disregard -this ordering. +Response serialization formats capable of representing ordered maps should +maintain this ordering. Serialization formats which can only represent unordered +maps should retain this order grammatically (such as JSON). + +Producing a response where fields are represented in the same order in which +they appear in the request improves human readability during debugging and +enables more efficient parsing of responses if the order of properties can +be anticipated. If a fragment is spread before other fields, the fields that fragment specifies occur in the response before the following fields. diff --git a/spec/Section 7 -- Response.md b/spec/Section 7 -- Response.md index 14c950cf7..d28fcf7f4 100644 --- a/spec/Section 7 -- Response.md +++ b/spec/Section 7 -- Response.md @@ -21,9 +21,15 @@ representations of the following four primitives: * String * Null -Serialization formats which only support an ordered map (such as JSON) must -preserve ordering as it is defined by query execution. Serialization formats -which only support an unordered map may omit this ordering information. +Serialization formats which can represent an ordered map should preserve the +order of requested fields as defined by query execution. Serialization formats +which can only represent unordered maps should retain this order +grammatically (such as JSON). + +Producing a response where fields are represented in the same order in which +they appear in the request improves human readability during debugging and +enables more efficient parsing of responses if the order of properties can +be anticipated. A serialization format may support the following primitives, however, strings may be used as a substitute for those primitives. @@ -53,6 +59,24 @@ the following JSON concepts: | Float | Number | | Enum Value | String | +**Object Property Ordering** + +While JSON Objects are specified as an +[unordered collection of key-value pairs](https://tools.ietf.org/html/rfc7159#section-4) +the pairs are represented in an ordered manner. In other words, while the JSON +strings `{ "name": "Mark", "age": 30 }` and `{ "age": 30, "name": "Mark" }` +encode the same value, they also have observably different property orderings. + +Since the result of evaluating a selection set is ordered, the JSON object +serialized should preserve this order by writing the object properties in the +same order as those fields were requested as defined by query execution. + +For example, if the query was `{ name, age }`, a GraphQL server responding in +JSON should respond with `{ "name": "Mark", "age": 30 }` and should not respond +with `{ "age": 30, "name": "Mark" }`. + +NOTE: This does not violate the JSON spec, as clients may still interpret +objects in the response as unordered Maps and arrive at a valid value. ## Response Format