-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Editorial: Type kinds #970
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -264,32 +264,43 @@ TypeDefinition : | |||||||||||||||
- EnumTypeDefinition | ||||||||||||||||
- InputObjectTypeDefinition | ||||||||||||||||
|
||||||||||||||||
The fundamental unit of any GraphQL Schema is the type. There are six kinds of | ||||||||||||||||
The fundamental unit of any GraphQL schema is the type. There are six kinds of | ||||||||||||||||
named type definitions in GraphQL, and two wrapping types. | ||||||||||||||||
|
||||||||||||||||
The most basic type is a `Scalar`. A scalar represents a primitive value, like a | ||||||||||||||||
string or an integer. Oftentimes, the possible responses for a scalar field are | ||||||||||||||||
enumerable. GraphQL offers an `Enum` type in those cases, where the type | ||||||||||||||||
specifies the space of valid responses. | ||||||||||||||||
:: A _leaf type_ is a kind of type representing a primitive value which cannot | ||||||||||||||||
be further selected and thus form the leaves in a response tree. GraphQL | ||||||||||||||||
Comment on lines
+270
to
+271
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit wordy, but...
Suggested change
|
||||||||||||||||
provides two kinds of leaf types: `Scalar` and `Enum`. | ||||||||||||||||
|
||||||||||||||||
Scalars and Enums form the leaves in response trees; the intermediate levels are | ||||||||||||||||
`Object` types, which define a set of fields, where each field is another type | ||||||||||||||||
in the system, allowing the definition of arbitrary type hierarchies. | ||||||||||||||||
A `Scalar` represents a primitive scalar value, such as a string or number. | ||||||||||||||||
Oftentimes, the possible responses for a scalar field are enumerable. GraphQL | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
offers an `Enum` type in those cases, where the type specifies the set of valid | ||||||||||||||||
responses. | ||||||||||||||||
|
||||||||||||||||
GraphQL supports two abstract types: interfaces and unions. | ||||||||||||||||
:: A _composite type_ is a type composed of other types via a set of named | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. need consistency in capitalizing - if 'Leaf type' then 'Composite type' |
||||||||||||||||
fields. Each field may provide a _leaf type_ or another composite type (or | ||||||||||||||||
wrapped types of either), allowing for the definition of arbitrary type | ||||||||||||||||
hierarchies. | ||||||||||||||||
|
||||||||||||||||
An `Interface` defines a list of fields; `Object` types and other Interface | ||||||||||||||||
types which implement this Interface are guaranteed to implement those fields. | ||||||||||||||||
Whenever a field claims it will return an Interface type, it will return a valid | ||||||||||||||||
implementing Object type during execution. | ||||||||||||||||
An `Object` type is a _composite type_ representing composite values selectable | ||||||||||||||||
within a GraphQL operation. They provide the intermediate levels of a schema, | ||||||||||||||||
allowing GraphQL to describe an interconnected graph of information. | ||||||||||||||||
|
||||||||||||||||
A `Union` defines a list of possible types; similar to interfaces, whenever the | ||||||||||||||||
type system claims a union will be returned, one of the possible types will be | ||||||||||||||||
returned. | ||||||||||||||||
:: An _abstract type_ allows a GraphQL schema to introduce polymorphism; where a | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it should be comma after polymorphism, not semicolon. |
||||||||||||||||
field may provide one of many possible types at runtime. GraphQL provides two | ||||||||||||||||
kinds of abstract types: `Interface` and `Union`. | ||||||||||||||||
|
||||||||||||||||
An `Interface` defines a list of fields; `Object` types and other `Interface` | ||||||||||||||||
types which implement this `Interface` are guaranteed to implement those fields. | ||||||||||||||||
Whenever a field claims it will return an `Interface` type, it will return a | ||||||||||||||||
valid implementing `Object` type during execution. | ||||||||||||||||
|
||||||||||||||||
A `Union` defines a list of possible types. Similar to `Interfaces`, whenever a | ||||||||||||||||
field claims it will return a `Union` type, it will return one of the possible | ||||||||||||||||
`Object` types during execution. | ||||||||||||||||
|
||||||||||||||||
Finally, oftentimes it is useful to provide complex structs as inputs to GraphQL | ||||||||||||||||
field arguments or variables; the `Input Object` type allows the schema to | ||||||||||||||||
define exactly what data is expected. | ||||||||||||||||
field arguments or variables; the `Input Object` type is a _composite type_ | ||||||||||||||||
which allows the schema to define more complex expected input data. | ||||||||||||||||
|
||||||||||||||||
### Wrapping Types | ||||||||||||||||
|
||||||||||||||||
|
@@ -635,14 +646,14 @@ FieldDefinition : Description? Name ArgumentsDefinition? : Type | |||||||||||||||
Directives[Const]? | ||||||||||||||||
|
||||||||||||||||
GraphQL operations are hierarchical and composed, describing a tree of | ||||||||||||||||
information. While Scalar types describe the leaf values of these hierarchical | ||||||||||||||||
information. While _leaf types_ describe the leaf values of these hierarchical | ||||||||||||||||
operations, Objects describe the intermediate levels. | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Objects (and lists) descr... |
||||||||||||||||
|
||||||||||||||||
GraphQL Objects represent a list of named fields, each of which yield a value of | ||||||||||||||||
a specific type. Object values should be serialized as ordered maps, where the | ||||||||||||||||
selected 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 selection | ||||||||||||||||
set. | ||||||||||||||||
GraphQL Objects are a _composite type_ representing a list of named fields, each | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
of which yield a value of a specific type. Object values should be serialized as | ||||||||||||||||
ordered maps, where the selected 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 selection set. | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we might mention here that field names might repeat in this output map, as a result of field merging |
||||||||||||||||
|
||||||||||||||||
All fields defined within an Object type must not have a name which begins with | ||||||||||||||||
{"\_\_"} (two underscores), as this is used exclusively by GraphQL's | ||||||||||||||||
|
@@ -1052,9 +1063,14 @@ InterfaceTypeDefinition : | |||||||||||||||
- Description? interface Name ImplementsInterfaces? Directives[Const]? | ||||||||||||||||
[lookahead != `{`] | ||||||||||||||||
|
||||||||||||||||
GraphQL interfaces represent a list of named fields and their arguments. GraphQL | ||||||||||||||||
objects and interfaces can then implement these interfaces which requires that | ||||||||||||||||
the implementing type will define all fields defined by those interfaces. | ||||||||||||||||
GraphQL interfaces are an _abstract type_ which when used as the type of a field | ||||||||||||||||
provides polymorphism where any implementation may be a possible type during | ||||||||||||||||
execution. | ||||||||||||||||
Comment on lines
+1066
to
+1068
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously it was stated that an interface may implement an interface. So "any implementation" could be perceived as including object types and interfaces. Let's clarify:
Suggested change
|
||||||||||||||||
|
||||||||||||||||
Interfaces are also a _composite type_ as they represent a list of named fields | ||||||||||||||||
and their arguments. An object or interface can declare that it implements an | ||||||||||||||||
interface which requires that the implementing type will define all fields | ||||||||||||||||
defined by that interface. | ||||||||||||||||
|
||||||||||||||||
Fields on a GraphQL interface have the same rules as fields on a GraphQL object; | ||||||||||||||||
their type can be Scalar, Object, Enum, Interface, or Union, or any wrapping | ||||||||||||||||
|
@@ -1304,17 +1320,18 @@ UnionMemberTypes : | |||||||||||||||
- UnionMemberTypes | NamedType | ||||||||||||||||
- = `|`? NamedType | ||||||||||||||||
|
||||||||||||||||
GraphQL Unions represent an object that could be one of a list of GraphQL Object | ||||||||||||||||
types, but provides for no guaranteed fields between those types. They also | ||||||||||||||||
differ from interfaces in that Object types declare what interfaces they | ||||||||||||||||
implement, but are not aware of what unions contain them. | ||||||||||||||||
GraphQL Unions are an _abstract type_ representing one of a list of GraphQL | ||||||||||||||||
Object possible types, but provides for no guaranteed fields between those | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. provides -> provide ? since Unions (plural) |
||||||||||||||||
types. They also differ from interfaces in that Object types declare what | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ? Feel free to dismiss.
Suggested change
Definitely what -> which though?
Suggested change
|
||||||||||||||||
interfaces they implement, but are not aware of what unions contain them. | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
|
||||||||||||||||
With interfaces and objects, only those fields defined on the type can be | ||||||||||||||||
queried directly; to query other fields on an interface, typed fragments must be | ||||||||||||||||
used. This is the same as for unions, but unions do not define any fields, so | ||||||||||||||||
**no** fields may be queried on this type without the use of type refining | ||||||||||||||||
fragments or inline fragments (with the exception of the meta-field | ||||||||||||||||
{\_\_typename}). | ||||||||||||||||
{\_\_typename}). Despite this, a union is still considered a _composite type_ as | ||||||||||||||||
it cannot represent a _leaf type_. | ||||||||||||||||
|
||||||||||||||||
For example, we might define the following types: | ||||||||||||||||
|
||||||||||||||||
|
@@ -1429,8 +1446,9 @@ EnumValuesDefinition : { EnumValueDefinition+ } | |||||||||||||||
|
||||||||||||||||
EnumValueDefinition : Description? EnumValue Directives[Const]? | ||||||||||||||||
|
||||||||||||||||
GraphQL Enum types, like Scalar types, also represent leaf values in a GraphQL | ||||||||||||||||
type system. However Enum types describe the set of possible values. | ||||||||||||||||
GraphQL Enum types, like Scalar types, are a _leaf type_ which represents a | ||||||||||||||||
_leaf field_ in a GraphQL type system. However Enum types describe the set of | ||||||||||||||||
Comment on lines
+1449
to
+1450
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Or simply:
Suggested change
|
||||||||||||||||
possible values. | ||||||||||||||||
|
||||||||||||||||
Enums are not references for a numeric value, but are unique values in their own | ||||||||||||||||
right. They may serialize as a string: the name of the represented value. | ||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -300,7 +300,7 @@ Fields\: | |||||||||||||
|
||||||||||||||
**Union** | ||||||||||||||
|
||||||||||||||
Unions are an abstract type where no common fields are declared. The possible | ||||||||||||||
Unions are an _abstract type_ where no common fields are declared. The possible | ||||||||||||||
types of a union are explicitly listed out in `possibleTypes`. Types can be made | ||||||||||||||
parts of unions without modification of that type. | ||||||||||||||
Comment on lines
304
to
305
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clarify:
Suggested change
|
||||||||||||||
|
||||||||||||||
|
@@ -315,10 +315,10 @@ Fields\: | |||||||||||||
|
||||||||||||||
**Interface** | ||||||||||||||
|
||||||||||||||
Interfaces are an abstract type where there are common fields declared. Any type | ||||||||||||||
that implements an interface must define all the fields with names and types | ||||||||||||||
exactly matching. The implementations of this interface are explicitly listed | ||||||||||||||
out in `possibleTypes`. | ||||||||||||||
Interfaces are an _abstract type_ where there are common fields declared. Any | ||||||||||||||
type that implements an interface must define all the fields with names and | ||||||||||||||
types exactly matching. The implementations of this interface are explicitly | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not think we require exact matching of type for implementing field. It can be derived/compatible type
Comment on lines
+319
to
+320
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clarify only the object types are in possibleTypes, and that types must be compatible.
Suggested change
|
||||||||||||||
listed out in `possibleTypes`. | ||||||||||||||
|
||||||||||||||
Fields\: | ||||||||||||||
|
||||||||||||||
|
@@ -351,9 +351,9 @@ Fields\: | |||||||||||||
|
||||||||||||||
**Input Object** | ||||||||||||||
|
||||||||||||||
Input objects are composite types defined as a list of named input values. They | ||||||||||||||
are only used as inputs to arguments and variables and cannot be a field return | ||||||||||||||
type. | ||||||||||||||
Input Objects are a _composite type_ defined as a list of named input field | ||||||||||||||
values. They are only used as inputs to arguments and variables and cannot be a | ||||||||||||||
field return type. | ||||||||||||||
Comment on lines
+354
to
+356
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Want to make it clear that input objects can be comprised of other input objects, and thus they are not only the full input to arguments but also parts thereof. I'm not sure if dropping the
Suggested change
|
||||||||||||||
|
||||||||||||||
For example the input object `Point` could be defined as: | ||||||||||||||
|
||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -446,7 +446,7 @@ SameResponseShape(fieldA, fieldB): | |||||||||
- If {typeA} or {typeB} is Scalar or Enum: | ||||||||||
- If {typeA} and {typeB} are the same type return true, otherwise return | ||||||||||
false. | ||||||||||
- Assert: {typeA} and {typeB} are both composite types. | ||||||||||
- Assert: {typeA} and {typeB} are both Object, Interface or Union. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be considered as
Suggested change
|
||||||||||
- Let {mergedSet} be the result of adding the selection set of {fieldA} and the | ||||||||||
selection set of {fieldB}. | ||||||||||
- Let {fieldsForName} be the set of selections with a given response name in | ||||||||||
|
@@ -555,8 +555,8 @@ fragment safeDifferingArgs on Pet { | |||||||||
} | ||||||||||
``` | ||||||||||
|
||||||||||
However, the field responses must be shapes which can be merged. For example, | ||||||||||
scalar values must not differ. In this example, `someValue` might be a `String` | ||||||||||
However, the field responses must be shapes which can be merged, and _leaf | ||||||||||
field_ types must not differ. In this example, `someValue` might be a `String` | ||||||||||
or an `Int`: | ||||||||||
|
||||||||||
```graphql counter-example | ||||||||||
|
@@ -583,8 +583,8 @@ fragment conflictingDifferingResponses on Pet { | |||||||||
|
||||||||||
**Explanatory Text** | ||||||||||
|
||||||||||
A field subselection is not allowed on leaf fields. A leaf field is any field | ||||||||||
with a scalar or enum unwrapped type. | ||||||||||
A field subselection is not allowed on a _leaf field_, a field with a Scalar or | ||||||||||
Enum unwrapped type. | ||||||||||
Comment on lines
+586
to
+587
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use parenthesis to make it clear this isn't a list:
Suggested change
|
||||||||||
|
||||||||||
The following is valid. | ||||||||||
|
||||||||||
|
@@ -1145,8 +1145,9 @@ fragment catInDogFragmentInvalid on Dog { | |||||||||
|
||||||||||
##### Abstract Spreads in Object Scope | ||||||||||
|
||||||||||
In scope of an object type, unions or interface spreads can be used if the | ||||||||||
object type implements the interface or is a member of the union. | ||||||||||
In scope of an object type, a fragment spread of an _abstract type_ (interface | ||||||||||
or union) can be used if the object type is one of the possible types of that | ||||||||||
abstract type (it implements the interface or is a member of the union). | ||||||||||
|
||||||||||
For example | ||||||||||
|
||||||||||
|
@@ -1183,9 +1184,9 @@ invalid because we only consider the fragment declaration, not its body. | |||||||||
|
||||||||||
##### Object Spreads In Abstract Scope | ||||||||||
|
||||||||||
Union or interface spreads can be used within the context of an object type | ||||||||||
fragment, but only if the object type is one of the possible types of that | ||||||||||
interface or union. | ||||||||||
In the scope of an _abstract type_ (interface or union), a fragment spread of an | ||||||||||
object type can be used if the object type is one of the possible types of that | ||||||||||
abstract type (it implements the interface or is a member of the union). | ||||||||||
|
||||||||||
For example, the following fragments are valid: | ||||||||||
|
||||||||||
|
@@ -1230,9 +1231,10 @@ can also never return meaningful results, making it invalid. | |||||||||
|
||||||||||
##### Abstract Spreads in Abstract Scope | ||||||||||
|
||||||||||
Union or interfaces fragments can be used within each other. As long as there | ||||||||||
exists at least _one_ object type that exists in the intersection of the | ||||||||||
possible types of the scope and the spread, the spread is considered valid. | ||||||||||
In the scope of an _abstract type_ (interface or union), a fragment spread of | ||||||||||
another _abstract type_ can be used as long as there exists at least _one_ | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Emphasis unnecessary?
Suggested change
|
||||||||||
object type that exists in the intersection of the possible types of the scope | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there exists... that exists ... suggest to rephrase |
||||||||||
and the spread. | ||||||||||
|
||||||||||
So for example | ||||||||||
|
||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -700,9 +700,9 @@ CompleteValue(fieldType, fields, result, variableValues): | |||||||
**Coercing Results** | ||||||||
|
||||||||
The primary purpose of value completion is to ensure that the values returned by | ||||||||
field resolvers are valid according to the GraphQL type system and a service's | ||||||||
schema. This "dynamic type checking" allows GraphQL to provide consistent | ||||||||
guarantees about returned types atop any service's internal runtime. | ||||||||
_leaf type_ field resolvers are valid according to the GraphQL type system and a | ||||||||
service's schema. This "dynamic type checking" allows GraphQL to provide | ||||||||
consistent guarantees about returned types atop any service's internal runtime. | ||||||||
|
||||||||
See the Scalars | ||||||||
[Result Coercion and Serialization](#sec-Scalars.Result-Coercion-and-Serialization) | ||||||||
|
@@ -723,9 +723,9 @@ and output of {CoerceResult()} must not be {null}. | |||||||
|
||||||||
**Resolving Abstract Types** | ||||||||
|
||||||||
When completing a field with an abstract return type, that is an Interface or | ||||||||
Union return type, first the abstract type must be resolved to a relevant Object | ||||||||
type. This determination is made by the internal system using whatever means | ||||||||
When completing a field with an _abstract type_, that is an Interface or Union | ||||||||
return type, first the abstract type must be resolved to a relevant Object type. | ||||||||
Comment on lines
+726
to
+727
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alternative wording:
Suggested change
"a suitable object type" or "the relevant object type" I think? |
||||||||
This determination is made by the internal system using whatever means | ||||||||
appropriate. | ||||||||
|
||||||||
Note: A common method of determining the Object type for an {objectValue} in | ||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
something does not match; if subject is 'kind' (singular) then the verb should be 'forms' (singular)
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General suggestion
I think 'kind of type' is confusing, since we have already TYPE_KIND, different kind. What we introduce here are groups of types, sort of, purely for easier references in the spec; these groups or categories do not appear anywhere at runtime or in graphql artifacts - purely for shorter and simpler spec references.
So instead of
A Leaf type is a kind of type representing ...
we can say simply
Leaf types are types representing
without even explicitly calling it a group or category
(Edit) PS - actually this way (without kind) is phrased in other cases, so we would need to just change this spot.