Skip to content

Commit 18e70e5

Browse files
committed
allow unions to include interfaces and unions
1 parent 7908822 commit 18e70e5

File tree

2 files changed

+71
-12
lines changed

2 files changed

+71
-12
lines changed

spec/Section 3 -- Type System.md

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -923,8 +923,8 @@ IsValidImplementationFieldType(fieldType, implementedFieldType):
923923
3. Return {IsValidImplementationFieldType(itemType, implementedItemType)}.
924924
3. If {fieldType} is the same type as {implementedFieldType} then return {true}.
925925
4. If {fieldType} is an Object type and {implementedFieldType} is a Union type
926-
and {fieldType} is a possible type of {implementedFieldType} then return
927-
{true}.
926+
and {fieldType} is a possible type or member type of {implementedFieldType}
927+
then return {true}.
928928
5. If {fieldType} is an Object or Interface type and {implementedFieldType} is
929929
an Interface type and {fieldType} declares it implements
930930
{implementedFieldType} then return {true}.
@@ -1302,8 +1302,8 @@ UnionMemberTypes :
13021302
- = `|`? NamedType
13031303

13041304
GraphQL Unions represent an object that could be one of a list of GraphQL Object
1305-
types, but provides for no guaranteed fields between those types. They also
1306-
differ from interfaces in that Object types declare what interfaces they
1305+
types, providing for no guaranteed fields between those types. They differ from
1306+
interfaces in that Object and Interface types declare what interfaces they
13071307
implement, but are not aware of what unions contain them.
13081308

13091309
With interfaces and objects, only those fields defined on the type can be
@@ -1370,6 +1370,61 @@ union SearchResult =
13701370
| Person
13711371
```
13721372

1373+
**Unions of Interfaces and Unions**
1374+
1375+
A Union may declare interfaces or other unions as member types. The parent
1376+
Union's possible types transitively include all the possible types of any
1377+
abstract member types. For example, the following types are valid:
1378+
1379+
```graphql example
1380+
union SearchResult = Photo | Named
1381+
1382+
interface Named {
1383+
name: String
1384+
}
1385+
1386+
type Person {
1387+
name: String
1388+
age: Int
1389+
}
1390+
1391+
union Item = Photo | Video
1392+
1393+
type Photo {
1394+
height: Int
1395+
width: Int
1396+
}
1397+
1398+
type Video {
1399+
codec: String
1400+
}
1401+
1402+
type SearchQuery {
1403+
firstSearchResult: SearchResult
1404+
}
1405+
```
1406+
1407+
And, given the above, the following operation is valid:
1408+
1409+
```graphql example
1410+
{
1411+
firstSearchResult {
1412+
... on Named {
1413+
name
1414+
}
1415+
... on Person {
1416+
age
1417+
}
1418+
... on Photo {
1419+
height
1420+
}
1421+
... on Video {
1422+
codec
1423+
}
1424+
}
1425+
}
1426+
```
1427+
13731428
**Result Coercion**
13741429

13751430
The union type should have some way of determining which object a given result
@@ -1385,8 +1440,8 @@ Unions are never valid inputs.
13851440
Union types have the potential to be invalid if incorrectly defined.
13861441

13871442
1. A Union type must include one or more unique member types.
1388-
2. The member types of a Union type must all be Object base types; Scalar,
1389-
Interface and Union types must not be member types of a Union. Similarly,
1443+
2. The member types of a Union type must all be Object, Interface or Union
1444+
types; Scalar and Enum types must not be member types of a Union. Similarly,
13901445
wrapping types must not be member types of a Union.
13911446

13921447
### Union Extensions
@@ -1406,9 +1461,9 @@ another GraphQL service.
14061461
Union type extensions have the potential to be invalid if incorrectly defined.
14071462

14081463
1. The named type must already be defined and must be a Union type.
1409-
2. The member types of a Union type extension must all be Object base types;
1410-
Scalar, Interface and Union types must not be member types of a Union.
1411-
Similarly, wrapping types must not be member types of a Union.
1464+
2. The member types of a Union type must all be Object, Interface or Union
1465+
types; Scalar and Enum types must not be member types of a Union. Similarly,
1466+
wrapping types must not be member types of a Union.
14121467
3. All member types of a Union type extension must be unique.
14131468
4. All member types of a Union type extension must not already be a member of
14141469
the original Union type.

spec/Section 4 -- Introspection.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ type __Type {
140140
fields(includeDeprecated: Boolean = false): [__Field!]
141141
# must be non-null for OBJECT and INTERFACE, otherwise null.
142142
interfaces: [__Type!]
143+
# must be non-null for UNION, otherwise null.
144+
memberTypes: [__Type!]
143145
# must be non-null for INTERFACE and UNION, otherwise null.
144146
possibleTypes: [__Type!]
145147
# must be non-null for ENUM, otherwise null.
@@ -297,7 +299,8 @@ Fields\:
297299

298300
**Union**
299301

300-
Unions are an abstract type where no common fields are declared. The possible
302+
Unions are an abstract type where no common fields are declared. The declared
303+
member types of a union are accessible via `memberTypes`. The possible Object
301304
types of a union are explicitly listed out in `possibleTypes`. Types can be made
302305
parts of unions without modification of that type.
303306

@@ -306,8 +309,9 @@ Fields\:
306309
- `kind` must return `__TypeKind.UNION`.
307310
- `name` must return a String.
308311
- `description` may return a String or {null}.
309-
- `possibleTypes` returns the list of types that can be represented within this
310-
union. They must be object types.
312+
- `memberTypes` returns the list of member types declared by the union.
313+
- `possibleTypes` returns the list of Object types that can be represented
314+
within this union.
311315
- All other fields must return {null}.
312316

313317
**Interface**

0 commit comments

Comments
 (0)