Skip to content

Commit fef43fa

Browse files
authored
specification adjustments related to the merge stage of composition (#143)
1 parent 64f7e0e commit fef43fa

File tree

1 file changed

+57
-51
lines changed

1 file changed

+57
-51
lines changed

spec/Section 4 -- Composition.md

+57-51
Original file line numberDiff line numberDiff line change
@@ -3416,18 +3416,18 @@ MergeInterfaceTypes(types):
34163416
- Let {firstType} be the first type in {types}.
34173417
- Let {typeName} be the name of {firstType}.
34183418
- Let {description} be the description of {firstType}.
3419-
- Let {fields} be an empty set.
3419+
- Let {mergedFields} be an empty set.
34203420
- For each {type} in {types}:
34213421
- If {description} is {null}:
34223422
- Set {description} to the description of {type}.
34233423
- Let {fieldNames} be the set of all field names in {types}.
34243424
- For each {fieldName} in {fieldNames}:
3425-
- Let {field} be the set of fields with the name {fieldName} in {types}.
3426-
- Let {mergedField} be the result of {MergeFieldDefinitions(fields)}.
3425+
- Let {fields} be the set of fields with the name {fieldName} in {types}.
3426+
- Let {mergedField} be the result of {MergeOutputFields(fields)}.
34273427
- If {mergedField} is not {null}:
3428-
- Add {mergedField} to {fields}.
3428+
- Add {mergedField} to {mergedFields}.
34293429
- Return a new interface type with the name of {typeName}, description of
3430-
{description}, and fields of {fields}.
3430+
{description}, and fields of {mergedFields}.
34313431

34323432
**Explanatory Text**
34333433

@@ -3450,9 +3450,9 @@ interface has none.
34503450
_Merging Fields_
34513451

34523452
Each interface contributes its fields. Those fields that share the same name
3453-
across multiple interfaces are reconciled via {MergeFieldDefinitions(fields)}.
3454-
This ensures any differences in type, nullability, or other constraints are
3455-
resolved before appearing in the final interface.
3453+
across multiple interfaces are reconciled via {MergeOutputFields(fields)}. This
3454+
ensures any differences in type, nullability, or other constraints are resolved
3455+
before appearing in the final interface.
34563456

34573457
By applying these steps, {MergeInterfaceTypes(types)} produces a coherent
34583458
interface type definition that reflects the fields from all compatible sources
@@ -3480,7 +3480,7 @@ interface Product {
34803480

34813481
# Composed Result
34823482

3483-
interface Entity {
3483+
interface Product {
34843484
id: ID!
34853485
name: String
34863486
createdAt: String
@@ -3742,16 +3742,18 @@ MergeInputTypes(types):
37423742
- Let {firstType} be the first type in {types}.
37433743
- Let {typeName} be the name of {firstType}.
37443744
- Let {description} be the description of {firstType}.
3745-
- Let {fields} be an empty set.
3745+
- Let {mergedFields} be an empty set.
37463746
- For each {type} in {types}:
37473747
- If {description} is {null}:
37483748
- Set {description} to the description of {type}.
37493749
- Let {fieldNames} be the set of all field names in {types}.
37503750
- For each {fieldName} in {fieldNames}:
3751-
- Let {field} be the set of fields with the name {fieldName} in {types}.
3752-
- Let {mergedField} be the result of {MergeInputField(fields)}.
3751+
- Let {fields} be the set of fields with the name {fieldName} in {types}.
3752+
- Let {mergedField} be the result of {MergeInputFields(fields)}.
37533753
- If {mergedField} is not {null}:
3754-
- Add {mergedField} to {fields}.
3754+
- Add {mergedField} to {mergedFields}.
3755+
- Return a new input object type with the name of {typeName}, description of
3756+
{description}, fields of {mergedFields}.
37553757

37563758
**Explanatory Text**
37573759

@@ -3776,12 +3778,12 @@ definition has no description.
37763778
_Merging Fields_
37773779

37783780
After filtering out inaccessible types, the algorithm merges each input field
3779-
name found across the remaining types. For each field, {MergeInputField(fields)}
3780-
is called to reconcile differences in type, nullability, default values, etc..
3781-
If a merged field ends up being `null` - for instance, because one of its
3782-
underlying definitions was inaccessible - that field is not included in the
3783-
final definition. The end result is a single input type that correctly unifies
3784-
every compatible field from the various sources.
3781+
name found across the remaining types. For each field,
3782+
{MergeInputFields(fields)} is called to reconcile differences in type,
3783+
nullability, default values, etc.. If a merged field ends up being `null` - for
3784+
instance, because one of its underlying definitions was inaccessible - that
3785+
field is not included in the final definition. The end result is a single input
3786+
type that correctly unifies every compatible field from the various sources.
37853787

37863788
**Examples**
37873789

@@ -3860,21 +3862,23 @@ MergeObjectTypes(types):
38603862
- If any {type} in {types} is marked with `@inaccessible`
38613863
- Return {null}
38623864
- Remove all types marked with `@internal` from {types}.
3865+
- If {types} is empty:
3866+
- Return {null}
38633867
- Let {firstType} be the first type in {types}.
38643868
- Let {typeName} be the name of {firstType}.
38653869
- Let {description} be the description of {firstType}.
3866-
- Let {fields} be an empty set.
3870+
- Let {mergedFields} be an empty set.
38673871
- For each {type} in {types}:
38683872
- If {description} is {null}:
38693873
- Set {description} to the description of {type}.
38703874
- Let {fieldNames} be the set of all field names in {types}.
38713875
- For each {fieldName} in {fieldNames}:
3872-
- Let {field} be the set of fields with the name {fieldName} in {types}.
3873-
- Let {mergedField} be the result of {MergeOutputField(fields)}.
3876+
- Let {fields} be the set of fields with the name {fieldName} in {types}.
3877+
- Let {mergedField} be the result of {MergeOutputFields(fields)}.
38743878
- If {mergedField} is not {null}:
3875-
- Add {mergedField} to {fields}.
3879+
- Add {mergedField} to {mergedFields}.
38763880
- Return a new object type with the name of {typeName}, description of
3877-
{description}, fields of {fields}.
3881+
{description}, fields of {mergedFields}.
38783882

38793883
**Explanatory Text**
38803884

@@ -3904,8 +3908,8 @@ simply has no description.
39043908
_Merging Fields_
39053909

39063910
All remaining object types contribute their fields. The algorithm gathers every
3907-
field name across these types, then calls {MergeOutputField(fields)} for each
3908-
name to reconcile any differences. If {MergeOutputField(fields)} returns {null}
3911+
field name across these types, then calls {MergeOutputFields(fields)} for each
3912+
name to reconcile any differences. If {MergeOutputFields(fields)} returns {null}
39093913
(for instance, because a field is marked `@inaccessible`), that field is
39103914
excluded from the final object type. The result is a unified set of fields that
39113915
reflects each source definition while maintaining compatibility across them.
@@ -4006,11 +4010,11 @@ type Product {
40064010
}
40074011
```
40084012

4009-
#### Merge Output Field
4013+
#### Merge Output Fields
40104014

40114015
**Formal Specification**
40124016

4013-
MergeOutputField(fields):
4017+
MergeOutputFields(fields):
40144018

40154019
- If any {field} in {fields} is marked with `@inaccessible`
40164020
- Return {null}
@@ -4022,23 +4026,24 @@ MergeOutputField(fields):
40224026
- Let {fieldType} be the type of {firstField}.
40234027
- Let {description} be the description of {firstField}.
40244028
- For each {field} in {fields}:
4029+
- Let {type} be the type of {field}.
40254030
- Set {fieldType} to be the result of {LeastRestrictiveType(fieldType, type)}.
40264031
- If {description} is {null}:
40274032
- Let {description} be the description of {field}.
4028-
- Let {arguments} be an empty set.
4033+
- Let {mergedArguments} be an empty set.
40294034
- Let {argumentNames} be the set of all argument names in {fields}.
40304035
- For each {argumentName} in {argumentNames}:
40314036
- Let {arguments} be the set of arguments with the name {argumentName} in
40324037
{fields}.
40334038
- Let {mergedArgument} be the result of {MergeArgumentDefinitions(arguments)}.
4034-
- If {mergedArguments} is not {null}:
4035-
- Add {mergedArgument} to {arguments}.
4039+
- If {mergedArgument} is not {null}:
4040+
- Add {mergedArgument} to {mergedArguments}.
40364041
- Return a new field with the name of {fieldName}, type of {fieldType},
4037-
arguments of {arguments}, and description of {description}.
4042+
arguments of {mergedArguments}, and description of {description}.
40384043

40394044
**Explanatory Text**
40404045

4041-
The {MergeOutputField(fields)} algorithm is used when multiple fields across
4046+
The {MergeOutputFields(fields)} algorithm is used when multiple fields across
40424047
different object or interface types share the same field name and must be merged
40434048
into a single composed field. This algorithm ensures that the final composed
40444049
schema has one definitive definition for that field, resolving differences in
@@ -4121,11 +4126,11 @@ type Product {
41214126
}
41224127
```
41234128

4124-
#### Merge Input Field
4129+
#### Merge Input Fields
41254130

41264131
**Formal Specification**
41274132

4128-
MergeInputField(fields):
4133+
MergeInputFields(fields):
41294134

41304135
- If any {field} in {fields} is marked with `@inaccessible`
41314136
- Return null
@@ -4136,22 +4141,23 @@ MergeInputField(fields):
41364141
- Let {defaultValue} be the default value of {firstField} or undefined if none
41374142
exists.
41384143
- For each {field} in {fields}:
4144+
- Let {type} be the type of {field}.
41394145
- Set {fieldType} to be the result of {MostRestrictiveType(fieldType, type)}.
4146+
- If {description} is null:
4147+
- Let {description} be the description of {field}.
41404148
- If {defaultValue} is undefined:
41414149
- Set {defaultValue} to the default value of {field} or undefined if none
41424150
exists.
4143-
- If {description} is null:
4144-
- Let {description} be the description of {field}.
41454151
- Return a new input field with the name of {fieldName}, type of {fieldType},
41464152
and description of {description} and default value of {defaultValue}.
41474153

41484154
**Explanatory Text**
41494155

4150-
The {MergeInputField(fields)} algorithm merges multiple input field definitions,
4151-
all sharing the same field name, into a single composed input field. This
4152-
ensures the final input type in a composed schema maintains a consistent type,
4153-
description, and default value for that field. Below is a breakdown of how
4154-
{MergeInputField(fields)} operates:
4156+
The {MergeInputFields(fields)} algorithm merges multiple input field
4157+
definitions, all sharing the same field name, into a single composed input
4158+
field. This ensures the final input type in a composed schema maintains a
4159+
consistent type, description, and default value for that field. Below is a
4160+
breakdown of how {MergeInputFields(fields)} operates:
41554161

41564162
_Inaccessible Fields_
41574163

@@ -4207,7 +4213,7 @@ input OrderFilter {
42074213
"""
42084214
Filter by the minimum order total
42094215
"""
4210-
minTotal: Int = 0
4216+
minTotal: Int! = 0
42114217
}
42124218
```
42134219

@@ -4230,7 +4236,7 @@ MergeArgumentDefinitions(arguments):
42304236
- For each {argument} in {arguments}:
42314237
- If {argument} is marked with `@require`
42324238
- Continue
4233-
- Set {mergedArgument} to the result of {MergeArgument(mergedArgument,
4239+
- Set {mergedArgument} to the result of {MergeArguments(mergedArgument,
42344240
argument)}
42354241
- Return {mergedArgument}
42364242

@@ -4310,11 +4316,11 @@ In the merged schema, the `filter` argument is defined with the most restrictive
43104316
type (`ProductFilter!`), includes the description from the original field in
43114317
`Schema A`, and is marked as required.
43124318

4313-
#### Merge Argument
4319+
#### Merge Arguments
43144320

43154321
**Formal Specification**
43164322

4317-
MergeArgument(argumentA, argumentB):
4323+
MergeArguments(argumentA, argumentB):
43184324

43194325
- Let {typeA} be the type of {argumentA}.
43204326
- Let {typeB} be the type of {argumentB}.
@@ -4328,14 +4334,14 @@ MergeArgument(argumentA, argumentB):
43284334
- If {defaultValue} is undefined:
43294335
- Set {defaultValue} to the default value of {argumentB} or undefined if none
43304336
exists.
4331-
- Return a new argument with the name of {argumentA}, type of {type}, and
4332-
description of {description}.
4337+
- Return a new argument with the name of {argumentA}, type of {type},
4338+
description of {description}, and default value of {defaultValue}.
43334339

43344340
**Explanatory Text**
43354341

4336-
{MergeArgument(argumentA, argumentB)} takes two arguments with the same name but
4337-
possibly differing in type, description, or default value, and returns a single,
4338-
unified argument definition.
4342+
{MergeArguments(argumentA, argumentB)} takes two arguments with the same name
4343+
but possibly differing in type, description, or default value, and returns a
4344+
single, unified argument definition.
43394345

43404346
_Unifying the Type_
43414347

0 commit comments

Comments
 (0)