Skip to content

Commit 3b00fdb

Browse files
committed
Editorial: Type kinds
This provides definitions at the introduction of "Type System" for _leaf type_, _composite type_, and _abstract type_. Then, these definitions are used throughout the spec.
1 parent 47a6bfd commit 3b00fdb

File tree

5 files changed

+86
-64
lines changed

5 files changed

+86
-64
lines changed

spec/Section 2 -- Language.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,11 @@ piece of information available to request within a selection set.
357357

358358
Some fields describe complex data or relationships to other data. In order to
359359
further explore this data, a field may itself contain a selection set, allowing
360-
for deeply nested requests. All GraphQL operations must specify their selections
361-
down to fields which return scalar values to ensure an unambiguously shaped
362-
response.
360+
for deeply nested requests.
361+
362+
:: A _leaf field_ is a field whose unwrapped type is a Scalar or Enum _leaf
363+
type_. All GraphQL operations must specify their selections down to leaf fields
364+
to ensure an unambiguously shaped response.
363365

364366
For example, this operation selects fields of complex data and relationships
365367
down to scalar values.

spec/Section 3 -- Type System.md

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -264,32 +264,43 @@ TypeDefinition :
264264
- EnumTypeDefinition
265265
- InputObjectTypeDefinition
266266

267-
The fundamental unit of any GraphQL Schema is the type. There are six kinds of
267+
The fundamental unit of any GraphQL schema is the type. There are six kinds of
268268
named type definitions in GraphQL, and two wrapping types.
269269

270-
The most basic type is a `Scalar`. A scalar represents a primitive value, like a
271-
string or an integer. Oftentimes, the possible responses for a scalar field are
272-
enumerable. GraphQL offers an `Enum` type in those cases, where the type
273-
specifies the space of valid responses.
270+
:: A _leaf type_ is a kind of type representing a primitive value which cannot
271+
be further selected and thus form the leaves in a response tree. GraphQL
272+
provides two kinds of leaf types: `Scalar` and `Enum`.
274273

275-
Scalars and Enums form the leaves in response trees; the intermediate levels are
276-
`Object` types, which define a set of fields, where each field is another type
277-
in the system, allowing the definition of arbitrary type hierarchies.
274+
A `Scalar` represents a primitive scalar value, such as a string or number.
275+
Oftentimes, the possible responses for a scalar field are enumerable. GraphQL
276+
offers an `Enum` type in those cases, where the type specifies the set of valid
277+
responses.
278278

279-
GraphQL supports two abstract types: interfaces and unions.
279+
:: A _composite type_ is a type composed of other types via a set of named
280+
fields. Each field may provide a _leaf type_ or another composite type (or
281+
wrapped types of either), allowing for the definition of arbitrary type
282+
hierarchies.
280283

281-
An `Interface` defines a list of fields; `Object` types and other Interface
282-
types which implement this Interface are guaranteed to implement those fields.
283-
Whenever a field claims it will return an Interface type, it will return a valid
284-
implementing Object type during execution.
284+
An `Object` type is a _composite type_ representing composite values selectable
285+
within a GraphQL operation. They provide the intermediate levels of a schema,
286+
allowing GraphQL to describe an interconnected graph of information.
285287

286-
A `Union` defines a list of possible types; similar to interfaces, whenever the
287-
type system claims a union will be returned, one of the possible types will be
288-
returned.
288+
:: An _abstract type_ allows a GraphQL schema to introduce polymorphism; where a
289+
field may provide one of many possible types at runtime. GraphQL provides two
290+
kinds of abstract types: `Interface` and `Union`.
291+
292+
An `Interface` defines a list of fields; `Object` types and other `Interface`
293+
types which implement this `Interface` are guaranteed to implement those fields.
294+
Whenever a field claims it will return an `Interface` type, it will return a
295+
valid implementing `Object` type during execution.
296+
297+
A `Union` defines a list of possible types. Similar to `Interfaces`, whenever a
298+
field claims it will return a `Union` type, it will return one of the possible
299+
`Object` types during execution.
289300

290301
Finally, oftentimes it is useful to provide complex structs as inputs to GraphQL
291-
field arguments or variables; the `Input Object` type allows the schema to
292-
define exactly what data is expected.
302+
field arguments or variables; the `Input Object` type is a _composite type_
303+
which allows the schema to define more complex expected input data.
293304

294305
### Wrapping Types
295306

@@ -635,14 +646,14 @@ FieldDefinition : Description? Name ArgumentsDefinition? : Type
635646
Directives[Const]?
636647

637648
GraphQL operations are hierarchical and composed, describing a tree of
638-
information. While Scalar types describe the leaf values of these hierarchical
649+
information. While _leaf types_ describe the leaf values of these hierarchical
639650
operations, Objects describe the intermediate levels.
640651

641-
GraphQL Objects represent a list of named fields, each of which yield a value of
642-
a specific type. Object values should be serialized as ordered maps, where the
643-
selected field names (or aliases) are the keys and the result of evaluating the
644-
field is the value, ordered by the order in which they appear in the selection
645-
set.
652+
GraphQL Objects are a _composite type_ representing a list of named fields, each
653+
of which yield a value of a specific type. Object values should be serialized as
654+
ordered maps, where the selected field names (or aliases) are the keys and the
655+
result of evaluating the field is the value, ordered by the order in which they
656+
appear in the selection set.
646657

647658
All fields defined within an Object type must not have a name which begins with
648659
{"\_\_"} (two underscores), as this is used exclusively by GraphQL's
@@ -1052,9 +1063,14 @@ InterfaceTypeDefinition :
10521063
- Description? interface Name ImplementsInterfaces? Directives[Const]?
10531064
[lookahead != `{`]
10541065

1055-
GraphQL interfaces represent a list of named fields and their arguments. GraphQL
1056-
objects and interfaces can then implement these interfaces which requires that
1057-
the implementing type will define all fields defined by those interfaces.
1066+
GraphQL interfaces are an _abstract type_ which when used as the type of a field
1067+
provides polymorphism where any implementation may be a possible type during
1068+
execution.
1069+
1070+
Interfaces are also a _composite type_ as they represent a list of named fields
1071+
and their arguments. An object or interface can declare that it implements an
1072+
interface which requires that the implementing type will define all fields
1073+
defined by that interface.
10581074

10591075
Fields on a GraphQL interface have the same rules as fields on a GraphQL object;
10601076
their type can be Scalar, Object, Enum, Interface, or Union, or any wrapping
@@ -1304,17 +1320,18 @@ UnionMemberTypes :
13041320
- UnionMemberTypes | NamedType
13051321
- = `|`? NamedType
13061322

1307-
GraphQL Unions represent an object that could be one of a list of GraphQL Object
1308-
types, but provides for no guaranteed fields between those types. They also
1309-
differ from interfaces in that Object types declare what interfaces they
1310-
implement, but are not aware of what unions contain them.
1323+
GraphQL Unions are an _abstract type_ representing one of a list of GraphQL
1324+
Object possible types, but provides for no guaranteed fields between those
1325+
types. They also differ from interfaces in that Object types declare what
1326+
interfaces they implement, but are not aware of what unions contain them.
13111327

13121328
With interfaces and objects, only those fields defined on the type can be
13131329
queried directly; to query other fields on an interface, typed fragments must be
13141330
used. This is the same as for unions, but unions do not define any fields, so
13151331
**no** fields may be queried on this type without the use of type refining
13161332
fragments or inline fragments (with the exception of the meta-field
1317-
{\_\_typename}).
1333+
{\_\_typename}). Despite this, a union is still considered a _composite type_ as
1334+
it cannot represent a _leaf type_.
13181335

13191336
For example, we might define the following types:
13201337

@@ -1429,8 +1446,9 @@ EnumValuesDefinition : { EnumValueDefinition+ }
14291446

14301447
EnumValueDefinition : Description? EnumValue Directives[Const]?
14311448

1432-
GraphQL Enum types, like Scalar types, also represent leaf values in a GraphQL
1433-
type system. However Enum types describe the set of possible values.
1449+
GraphQL Enum types, like Scalar types, are a _leaf type_ which represents a
1450+
_leaf field_ in a GraphQL type system. However Enum types describe the set of
1451+
possible values.
14341452

14351453
Enums are not references for a numeric value, but are unique values in their own
14361454
right. They may serialize as a string: the name of the represented value.

spec/Section 4 -- Introspection.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ Fields\:
300300

301301
**Union**
302302

303-
Unions are an abstract type where no common fields are declared. The possible
303+
Unions are an _abstract type_ where no common fields are declared. The possible
304304
types of a union are explicitly listed out in `possibleTypes`. Types can be made
305305
parts of unions without modification of that type.
306306

@@ -315,10 +315,10 @@ Fields\:
315315

316316
**Interface**
317317

318-
Interfaces are an abstract type where there are common fields declared. Any type
319-
that implements an interface must define all the fields with names and types
320-
exactly matching. The implementations of this interface are explicitly listed
321-
out in `possibleTypes`.
318+
Interfaces are an _abstract type_ where there are common fields declared. Any
319+
type that implements an interface must define all the fields with names and
320+
types exactly matching. The implementations of this interface are explicitly
321+
listed out in `possibleTypes`.
322322

323323
Fields\:
324324

@@ -351,9 +351,9 @@ Fields\:
351351

352352
**Input Object**
353353

354-
Input objects are composite types defined as a list of named input values. They
355-
are only used as inputs to arguments and variables and cannot be a field return
356-
type.
354+
Input Objects are a _composite type_ defined as a list of named input field
355+
values. They are only used as inputs to arguments and variables and cannot be a
356+
field return type.
357357

358358
For example the input object `Point` could be defined as:
359359

spec/Section 5 -- Validation.md

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ SameResponseShape(fieldA, fieldB):
446446
- If {typeA} or {typeB} is Scalar or Enum:
447447
- If {typeA} and {typeB} are the same type return true, otherwise return
448448
false.
449-
- Assert: {typeA} and {typeB} are both composite types.
449+
- Assert: {typeA} and {typeB} are both Object, Interface or Union.
450450
- Let {mergedSet} be the result of adding the selection set of {fieldA} and the
451451
selection set of {fieldB}.
452452
- Let {fieldsForName} be the set of selections with a given response name in
@@ -555,8 +555,8 @@ fragment safeDifferingArgs on Pet {
555555
}
556556
```
557557

558-
However, the field responses must be shapes which can be merged. For example,
559-
scalar values must not differ. In this example, `someValue` might be a `String`
558+
However, the field responses must be shapes which can be merged, and _leaf
559+
field_ types must not differ. In this example, `someValue` might be a `String`
560560
or an `Int`:
561561

562562
```graphql counter-example
@@ -583,8 +583,8 @@ fragment conflictingDifferingResponses on Pet {
583583

584584
**Explanatory Text**
585585

586-
A field subselection is not allowed on leaf fields. A leaf field is any field
587-
with a scalar or enum unwrapped type.
586+
A field subselection is not allowed on a _leaf field_, a field with a Scalar or
587+
Enum unwrapped type.
588588

589589
The following is valid.
590590

@@ -1145,8 +1145,9 @@ fragment catInDogFragmentInvalid on Dog {
11451145

11461146
##### Abstract Spreads in Object Scope
11471147

1148-
In scope of an object type, unions or interface spreads can be used if the
1149-
object type implements the interface or is a member of the union.
1148+
In scope of an object type, a fragment spread of an _abstract type_ (interface
1149+
or union) can be used if the object type is one of the possible types of that
1150+
abstract type (it implements the interface or is a member of the union).
11501151

11511152
For example
11521153

@@ -1183,9 +1184,9 @@ invalid because we only consider the fragment declaration, not its body.
11831184

11841185
##### Object Spreads In Abstract Scope
11851186

1186-
Union or interface spreads can be used within the context of an object type
1187-
fragment, but only if the object type is one of the possible types of that
1188-
interface or union.
1187+
In the scope of an _abstract type_ (interface or union), a fragment spread of an
1188+
object type can be used if the object type is one of the possible types of that
1189+
abstract type (it implements the interface or is a member of the union).
11891190

11901191
For example, the following fragments are valid:
11911192

@@ -1230,9 +1231,10 @@ can also never return meaningful results, making it invalid.
12301231

12311232
##### Abstract Spreads in Abstract Scope
12321233

1233-
Union or interfaces fragments can be used within each other. As long as there
1234-
exists at least _one_ object type that exists in the intersection of the
1235-
possible types of the scope and the spread, the spread is considered valid.
1234+
In the scope of an _abstract type_ (interface or union), a fragment spread of
1235+
another _abstract type_ can be used as long as there exists at least _one_
1236+
object type that exists in the intersection of the possible types of the scope
1237+
and the spread.
12361238

12371239
So for example
12381240

spec/Section 6 -- Execution.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -700,9 +700,9 @@ CompleteValue(fieldType, fields, result, variableValues):
700700
**Coercing Results**
701701

702702
The primary purpose of value completion is to ensure that the values returned by
703-
field resolvers are valid according to the GraphQL type system and a service's
704-
schema. This "dynamic type checking" allows GraphQL to provide consistent
705-
guarantees about returned types atop any service's internal runtime.
703+
_leaf type_ field resolvers are valid according to the GraphQL type system and a
704+
service's schema. This "dynamic type checking" allows GraphQL to provide
705+
consistent guarantees about returned types atop any service's internal runtime.
706706

707707
See the Scalars
708708
[Result Coercion and Serialization](#sec-Scalars.Result-Coercion-and-Serialization)
@@ -723,9 +723,9 @@ and output of {CoerceResult()} must not be {null}.
723723

724724
**Resolving Abstract Types**
725725

726-
When completing a field with an abstract return type, that is an Interface or
727-
Union return type, first the abstract type must be resolved to a relevant Object
728-
type. This determination is made by the internal system using whatever means
726+
When completing a field with an _abstract type_, that is an Interface or Union
727+
return type, first the abstract type must be resolved to a relevant Object type.
728+
This determination is made by the internal system using whatever means
729729
appropriate.
730730

731731
Note: A common method of determining the Object type for an {objectValue} in

0 commit comments

Comments
 (0)