@@ -250,9 +250,10 @@ type in the system, allowing the definition of arbitrary type hierarchies.
250
250
251
251
GraphQL supports two abstract types: interfaces and unions.
252
252
253
- An ` Interface ` defines a list of fields; ` Object ` types that implement that
254
- interface are guaranteed to implement those fields. Whenever the type system
255
- claims it will return an interface, it will return a valid implementing type.
253
+ An ` Interface ` defines a list of fields; ` Object ` types and other Interface
254
+ types which implement this Interface are guaranteed to implement those fields.
255
+ Whenever a field claims it will return an Interface type, it will return a
256
+ valid implementing Object type during execution.
256
257
257
258
A ` Union ` defines a list of possible types; similar to interfaces, whenever the
258
259
type system claims a union will be returned, one of the possible types will be
@@ -810,31 +811,54 @@ of rules must be adhered to by every Object type in a GraphQL schema.
810
811
characters {"__ "} (two underscores).
811
812
2 . The argument must accept a type where {IsInputType(argumentType)}
812
813
returns {true}.
813
- 4 . An object type may declare that it implements one or more unique interfaces.
814
- 5 . An object type must be a super-set of all interfaces it implements:
815
- 1 . The object type must include a field of the same name for every field
816
- defined in an interface.
817
- 1 . The object field must be of a type which is equal to or a sub-type of
818
- the interface field (covariant).
819
- 1 . An object field type is a valid sub-type if it is equal to (the same
820
- type as) the interface field type.
821
- 2 . An object field type is a valid sub-type if it is an Object type and
822
- the interface field type is either an Interface type or a Union type
823
- and the object field type is a possible type of the interface field
824
- type.
825
- 3 . An object field type is a valid sub-type if it is a List type and
826
- the interface field type is also a List type and the list-item type
827
- of the object field type is a valid sub-type of the list-item type
828
- of the interface field type.
829
- 4 . An object field type is a valid sub-type if it is a Non-Null variant
830
- of a valid sub-type of the interface field type.
831
- 2 . The object field must include an argument of the same name for every
832
- argument defined in the interface field.
833
- 1 . The object field argument must accept the same type (invariant) as
834
- the interface field argument.
835
- 3 . The object field may include additional arguments not defined in the
836
- interface field, but any additional argument must not be required, e.g.
837
- must not be of a non-nullable type.
814
+ 3 . An object type may declare that it implements one or more unique interfaces.
815
+ 4 . An object type must be a super-set of all interfaces it implements:
816
+ 1 . Let this object type be {objectType}.
817
+ 2 . For each interface declared implemented as {interfaceType},
818
+ {IsValidImplementation(objectType, interfaceType)} must be {true}.
819
+
820
+ IsValidImplementation(type, implementedType):
821
+
822
+ 1 . If {implementedType} declares it implements any interfaces,
823
+ {type} must also declare it implements those interfaces.
824
+ 2 . {type} must include a field of the same name for every field
825
+ defined in {implementedType}.
826
+ 1 . Let {field} be that named field on {type}.
827
+ 2 . Let {implementedField} be that named field on {implementedType}.
828
+ 1 . {field} must include an argument of the same name for every argument
829
+ defined in {implementedField}.
830
+ 1 . That named argument on {field} must accept the same type
831
+ (invariant) as that named argument on {implementedField}.
832
+ 2 . {field} may include additional arguments not defined in
833
+ {implementedField}, but any additional argument must not be required,
834
+ e.g. must not be of a non-nullable type.
835
+ 3 . {field} must return a type which is equal to or a sub-type of
836
+ (covariant) the return type of {implementedField} field's return type:
837
+ 1 . Let {fieldType} be the return type of {field}.
838
+ 2 . Let {implementedFieldType} be the return type of {implementedField}.
839
+ 3 . {IsValidImplementationFieldType(fieldType, implementedFieldType)}
840
+ must be {true}.
841
+
842
+ IsValidImplementationFieldType(fieldType, implementedFieldType):
843
+ 1 . If {fieldType} is a Non-Null type:
844
+ 1 . Let {nullableType} be the unwrapped nullable type of {fieldType}.
845
+ 2 . Let {implementedNullableType} be the unwrapped nullable type
846
+ of {implementedFieldType} if it is a Non-Null type, otherwise let it be
847
+ {implementedFieldType} directly.
848
+ 3 . Return {IsValidImplementationFieldType(nullableType, implementedNullableType)}.
849
+ 2 . If {fieldType} is a List type and {implementedFieldType} is also a List type:
850
+ 1 . Let {itemType} be the unwrapped item type of {fieldType}.
851
+ 2 . Let {implementedItemType} be the unwrapped item type
852
+ of {implementedFieldType}.
853
+ 3 . Return {IsValidImplementationFieldType(itemType, implementedItemType)}.
854
+ 3 . If {fieldType} is the same type as {implementedFieldType} then return {true}.
855
+ 4 . If {fieldType} is an Object type and {implementedFieldType} is
856
+ a Union type and {fieldType} is a possible type of {implementedFieldType}
857
+ then return {true}.
858
+ 5 . If {fieldType} is an Object or Interface type and {implementedFieldType}
859
+ is an Interface type and {fieldType} declares it implements
860
+ {implementedFieldType} then return {true}.
861
+ 6 . Otherwise return {false}.
838
862
839
863
840
864
### Field Arguments
@@ -954,8 +978,8 @@ Object type extensions have the potential to be invalid if incorrectly defined.
954
978
InterfaceTypeDefinition : Description ? interface Name Directives [Const ]? FieldsDefinition ?
955
979
956
980
GraphQL interfaces represent a list of named fields and their arguments . GraphQL
957
- objects can then implement these interfaces which requires that the object type
958
- will define all fields defined by those interfaces .
981
+ objects and interfaces can then implement these interfaces which requires that
982
+ the implementing type will define all fields defined by those interfaces .
959
983
960
984
Fields on a GraphQL interface have the same rules as fields on a GraphQL object ;
961
985
their type can be Scalar , Object , Enum , Interface , or Union , or any wrapping
@@ -1045,6 +1069,63 @@ interface. Querying for `age` is only valid when the result of `entity` is a
1045
1069
}
1046
1070
```
1047
1071
1072
+ ** Interfaces Implementing Interfaces**
1073
+
1074
+ When defining an interface that implements another interface, the implementing
1075
+ interface must define each field that is specified by the implemented interface.
1076
+ For example, the interface Resource must define the field id to implement the
1077
+ Node interface:
1078
+
1079
+ ``` graphql example
1080
+ interface Node {
1081
+ id : ID !
1082
+ }
1083
+
1084
+ interface Resource implements Node {
1085
+ id : ID !
1086
+ url : String
1087
+ }
1088
+ ```
1089
+
1090
+ Transitively implemented interfaces (interfaces implemented by the interface
1091
+ that is being implemented) must also be defined on an implementing type or
1092
+ interface . For example , `Image ` cannot implement `Resource ` without also
1093
+ implementing `Node `:
1094
+
1095
+ ```graphql example
1096
+ interface Node {
1097
+ id : ID !
1098
+ }
1099
+
1100
+ interface Resource implements Node {
1101
+ id : ID !
1102
+ url : String
1103
+ }
1104
+
1105
+ interface Image implements Resource & Node {
1106
+ id : ID !
1107
+ url : String
1108
+ thumbnail : String
1109
+ }
1110
+ ```
1111
+
1112
+ Interface definitions must not contain cyclic references nor implement
1113
+ themselves . This example is invalid because `Node ` and `Named ` implement
1114
+ themselves and each other :
1115
+
1116
+ ```graphgl counter -example
1117
+ interface Node implements Named & Node {
1118
+ id : ID !
1119
+ name : String
1120
+ }
1121
+
1122
+ interface Named implements Node & Named {
1123
+ id : ID !
1124
+ name : String
1125
+ }
1126
+ ```
1127
+
1128
+
1048
1129
**Result Coercion **
1049
1130
1050
1131
The interface type should have some way of determining which object a given
@@ -1072,6 +1153,12 @@ Interface types have the potential to be invalid if incorrectly defined.
1072
1153
characters {"__" } (two underscores).
1073
1154
2. The argument must accept a type where {IsInputType (argumentType)}
1074
1155
returns {true }.
1156
+ 3. An interface type may declare that it implements one or more unique
1157
+ interfaces , but may not implement itself .
1158
+ 4. An interface type must be a super -set of all interfaces it implements :
1159
+ 1. Let this interface type be {implementingType }.
1160
+ 2. For each interface declared implemented as {implementedType },
1161
+ {IsValidImplementation (implementingType, implementedType)} must be {true }.
1075
1162
1076
1163
1077
1164
### Interface Extensions
@@ -1121,11 +1208,13 @@ Interface type extensions have the potential to be invalid if incorrectly define
1121
1208
fields may share the same name .
1122
1209
3. Any fields of an Interface type extension must not be already defined on the
1123
1210
original Interface type .
1124
- 4. Any Object type which implemented the original Interface type must also be a
1125
- super -set of the fields of the Interface type extension (which may be due to
1126
- Object type extension).
1211
+ 4. Any Object or Interface type which implemented the original Interface type
1212
+ must also be a super -set of the fields of the Interface type extension (which
1213
+ may be due to Object type extension).
1127
1214
5. Any non -repeatable directives provided must not already apply to the
1128
1215
original Interface type .
1216
+ 6. The resulting extended Interface type must be a super -set of all Interfaces
1217
+ it implements .
1129
1218
1130
1219
1131
1220
## Unions
0 commit comments