Skip to content

Commit 2e4d3ae

Browse files
authored
oosen must to should for serialization supporting ordered maps. (#191)
GraphQL should work correctly with many serialization techniques, not just JSON. Even within JSON, the GraphQL spec mentions ordered maps while the JSON spec describes unordered maps. This changes the language in the GraphQL spec to: * Use should instead of must where ordered map support might not be possible, thus supporting more environments. * Add clarifying language to JSON encoding section describing expectations for ordering. Fixes #168
1 parent 57a51f0 commit 2e4d3ae

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

spec/Section 3 -- Type System.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ While Scalar types describe the leaf values of these hierarchical queries, Objec
241241
describe the intermediate levels.
242242

243243
GraphQL Objects represent a list of named fields, each of which yield a value of
244-
a specific type. Object values are serialized as ordered maps, where the
244+
a specific type. Object values should be serialized as ordered maps, where the
245245
queried field names (or aliases) are the keys and the result of evaluating
246246
the field is the value, ordered by the order in which they appear in the query.
247247

@@ -261,8 +261,9 @@ that will yield an `Int` value, and `picture` is a field that will yield a
261261

262262
A query of an object value must select at least one field. This selection of
263263
fields will yield an ordered map containing exactly the subset of the object
264-
queried, in the order in which they were queried. Only fields that are declared
265-
on the object type may validly be queried on that object.
264+
queried, which should be represented in the order in which they were queried.
265+
Only fields that are declared on the object type may validly be queried on
266+
that object.
266267

267268
For example, selecting all the fields of `Person`:
268269

@@ -357,9 +358,14 @@ excluding fragments for which the type does not apply and fields or
357358
fragments that are skipped via `@skip` or `@include` directives. This ordering
358359
is correctly produced when using the {CollectFields()} algorithm.
359360

360-
Response formats which support ordered maps (such as JSON) must maintain this
361-
ordering. Response formats which do not support ordered maps may disregard
362-
this ordering.
361+
Response serialization formats capable of representing ordered maps should
362+
maintain this ordering. Serialization formats which can only represent unordered
363+
maps should retain this order grammatically (such as JSON).
364+
365+
Producing a response where fields are represented in the same order in which
366+
they appear in the request improves human readability during debugging and
367+
enables more efficient parsing of responses if the order of properties can
368+
be anticipated.
363369

364370
If a fragment is spread before other fields, the fields that fragment specifies
365371
occur in the response before the following fields.

spec/Section 7 -- Response.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,15 @@ representations of the following four primitives:
2121
* String
2222
* Null
2323

24-
Serialization formats which only support an ordered map (such as JSON) must
25-
preserve ordering as it is defined by query execution. Serialization formats
26-
which only support an unordered map may omit this ordering information.
24+
Serialization formats which can represent an ordered map should preserve the
25+
order of requested fields as defined by query execution. Serialization formats
26+
which can only represent unordered maps should retain this order
27+
grammatically (such as JSON).
28+
29+
Producing a response where fields are represented in the same order in which
30+
they appear in the request improves human readability during debugging and
31+
enables more efficient parsing of responses if the order of properties can
32+
be anticipated.
2733

2834
A serialization format may support the following primitives, however, strings
2935
may be used as a substitute for those primitives.
@@ -53,6 +59,24 @@ the following JSON concepts:
5359
| Float | Number |
5460
| Enum Value | String |
5561

62+
**Object Property Ordering**
63+
64+
While JSON Objects are specified as an
65+
[unordered collection of key-value pairs](https://tools.ietf.org/html/rfc7159#section-4)
66+
the pairs are represented in an ordered manner. In other words, while the JSON
67+
strings `{ "name": "Mark", "age": 30 }` and `{ "age": 30, "name": "Mark" }`
68+
encode the same value, they also have observably different property orderings.
69+
70+
Since the result of evaluating a selection set is ordered, the JSON object
71+
serialized should preserve this order by writing the object properties in the
72+
same order as those fields were requested as defined by query execution.
73+
74+
For example, if the query was `{ name, age }`, a GraphQL server responding in
75+
JSON should respond with `{ "name": "Mark", "age": 30 }` and should not respond
76+
with `{ "age": 30, "name": "Mark" }`.
77+
78+
NOTE: This does not violate the JSON spec, as clients may still interpret
79+
objects in the response as unordered Maps and arrive at a valid value.
5680

5781

5882
## Response Format

0 commit comments

Comments
 (0)