Skip to main content

Type system ordering of: object interfaces, directive arguments, input object fields, enum values

At a glance

Timeline


UPDATE 2024-04-05: Following last night's WG meeting, this PR has been split into 3 parts, and is now stacked behind these PRs:

  • #1102
  • #1092

As raised by @cdaringe in #1062, enum values don't dictate an explicit order. On scanning through the spec in more detail, it turns out this is true of a few other things too.

Everything in SDL is implicitly ordered (since it's a textual representation, one thing after another) and everything in introspection is implicitly ordered (because it's represented via lists). E.g. in introspection, enumValues is a list, and a list is inherently ordered.

I feel it's an unwritten rule that GraphQL introspection should be stable (i.e. introspect the exact same schema twice with the exact same introspection query and the results should be the same). Thus, there should be an order (dictated by the schema designer), and I'd like to make that more explicit.

I researched the current status, and I think we can start to fix this with the few minor edits I made to the spec in this PR, in particular:

  1. changing from using the word set (which is generally perceived as unordered) to the word list (which is always ordered),
  2. specifying list for things that are currently ambiguous.

Generally this was achieved by copying text from similar things, e.g. the directive arguments copied from field arguments; input object fields copied from object fields.

I know that @IvanGoncharov has been very careful in graphql-js to ensure that ordering is stable, I believe he ensures that introspection -> SDL -> introspection always results in the same results.

Status before this PR (emphasis mine)

Object fields: ordered

GraphQL Objects represent a list of named fields, each of which yield a value of a specific type.

Object field arguments: ordered

Object field arguments are defined as a list of all possible argument names and their expected input types

Object interfaces: not declared? 😞

An object type may declare that it implements one or more unique interfaces.

(I couldn't find anything in Section 3 declaring set/list.)

Input object fields: a "set"

A GraphQL Input Object defines a set of input fields

Enum values: a "set"

However Enum types describe the set of possible values

Directive arguments: not declared? 😞

(I couldn't find anything in Section 3 declaring set/list.)