Skip to content

Commit 19cb9c3

Browse files
committed
Align deferred fragment field collection with reference implementation
1 parent 7c5e1da commit 19cb9c3

File tree

1 file changed

+40
-17
lines changed

1 file changed

+40
-17
lines changed

spec/Section 6 -- Execution.md

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,9 @@ subsequentPayloads, asyncRecord):
411411

412412
- If {path} is not provided, initialize it to an empty list.
413413
- If {subsequentPayloads} is not provided, initialize it to the empty set.
414-
- Let {groupedFieldSet} be the result of {CollectFields(objectType, objectValue,
415-
selectionSet, variableValues, path subsequentPayloads, asyncRecord)}.
414+
- Let {groupedFieldSet} and {deferredGroupedFieldsList} be the result of
415+
{CollectFields(objectType, objectValue, selectionSet, variableValues, path,
416+
asyncRecord)}.
416417
- Initialize {resultMap} to an empty ordered map.
417418
- For each {groupedFieldSet} as {responseKey} and {fields}:
418419
- Let {fieldName} be the name of the first entry in {fields}. Note: This value
@@ -423,6 +424,10 @@ subsequentPayloads, asyncRecord):
423424
- Let {responseValue} be {ExecuteField(objectType, objectValue, fieldType,
424425
fields, variableValues, path, subsequentPayloads, asyncRecord)}.
425426
- Set {responseValue} as the value for {responseKey} in {resultMap}.
427+
- For each {deferredGroupFieldSet} and {label} in {deferredGroupedFieldsList}
428+
- Call {ExecuteDeferredFragment(label, objectType, objectValue,
429+
deferredGroupFieldSet, path, variableValues, asyncRecord,
430+
subsequentPayloads)}
426431
- Return {resultMap}.
427432

428433
Note: {resultMap} is ordered by which fields appear first in the operation. This
@@ -574,10 +579,12 @@ is maintained through execution, ensuring that fields appear in the executed
574579
response in a stable and predictable order.
575580

576581
CollectFields(objectType, objectValue, selectionSet, variableValues, path,
577-
subsequentPayloads, asyncRecord, visitedFragments):
582+
asyncRecord, visitedFragments, deferredGroupedFieldsList):
578583

579584
- If {visitedFragments} is not provided, initialize it to the empty set.
580585
- Initialize {groupedFields} to an empty ordered map of lists.
586+
- If {deferredGroupedFieldsList} is not provided, initialize it to an empty
587+
list.
581588
- For each {selection} in {selectionSet}:
582589
- If {selection} provides the directive `@skip`, let {skipDirective} be that
583590
directive.
@@ -616,13 +623,17 @@ subsequentPayloads, asyncRecord, visitedFragments):
616623
- If {deferDirective} is defined:
617624
- Let {label} be the value or the variable to {deferDirective}'s {label}
618625
argument.
619-
- Call {ExecuteDeferredFragment(label, objectType, objectValue,
620-
fragmentSelectionSet, path, variableValues, asyncRecord,
621-
subsequentPayloads)}.
626+
- Let {deferredGroupedFields} be the result of calling
627+
{CollectFields(objectType, objectValue, fragmentSelectionSet,
628+
variableValues, path, asyncRecord, visitedFragments,
629+
deferredGroupedFieldsList)}.
630+
- Append a record containing {label} and {deferredGroupedFields} to
631+
{deferredGroupedFieldsList}.
622632
- Continue with the next {selection} in {selectionSet}.
623633
- Let {fragmentGroupedFieldSet} be the result of calling
624634
{CollectFields(objectType, objectValue, fragmentSelectionSet,
625-
variableValues, path, subsequentPayloads, asyncRecord, visitedFragments)}.
635+
variableValues, path, asyncRecord, visitedFragments,
636+
deferredGroupedFieldsList)}.
626637
- For each {fragmentGroup} in {fragmentGroupedFieldSet}:
627638
- Let {responseKey} be the response key shared by all fields in
628639
{fragmentGroup}.
@@ -641,19 +652,24 @@ subsequentPayloads, asyncRecord, visitedFragments):
641652
{variableValues} with the value {true}:
642653
- Let {label} be the value or the variable to {deferDirective}'s {label}
643654
argument.
644-
- Call {ExecuteDeferredFragment(label, objectType, objectValue,
645-
fragmentSelectionSet, path, asyncRecord, subsequentPayloads)}.
655+
- Let {deferredGroupedFields} be the result of calling
656+
{CollectFields(objectType, objectValue, fragmentSelectionSet,
657+
variableValues, path, asyncRecord, visitedFragments,
658+
deferredGroupedFieldsList)}.
659+
- Append a record containing {label} and {deferredGroupedFields} to
660+
{deferredGroupedFieldsList}.
646661
- Continue with the next {selection} in {selectionSet}.
647662
- Let {fragmentGroupedFieldSet} be the result of calling
648663
{CollectFields(objectType, objectValue, fragmentSelectionSet,
649-
variableValues, path, subsequentPayloads, asyncRecord, visitedFragments)}.
664+
variableValues, path, asyncRecord, visitedFragments,
665+
deferredGroupedFieldsList)}.
650666
- For each {fragmentGroup} in {fragmentGroupedFieldSet}:
651667
- Let {responseKey} be the response key shared by all fields in
652668
{fragmentGroup}.
653669
- Let {groupForResponseKey} be the list in {groupedFields} for
654670
{responseKey}; if no such list exists, create it as an empty list.
655671
- Append all items in {fragmentGroup} to {groupForResponseKey}.
656-
- Return {groupedFields}.
672+
- Return {groupedFields} and {deferredGroupedFieldsList}.
657673

658674
Note: The steps in {CollectFields()} evaluating the `@skip` and `@include`
659675
directives may be applied in either order since they apply commutatively.
@@ -687,22 +703,29 @@ All Async Payload Records are structures containing:
687703

688704
#### Execute Deferred Fragment
689705

690-
ExecuteDeferredFragment(label, objectType, objectValue, fragmentSelectionSet,
691-
path, variableValues, parentRecord, subsequentPayloads):
706+
ExecuteDeferredFragment(label, objectType, objectValue, groupedFieldSet, path,
707+
variableValues, parentRecord, subsequentPayloads):
692708

693709
- Let {deferRecord} be an async payload record created from {label} and {path}.
694710
- Initialize {errors} on {deferRecord} to an empty list.
695711
- Let {dataExecution} be the asynchronous future value of:
696712
- Let {payload} be an unordered map.
697-
- Let {data} be the result of {ExecuteSelectionSet(fragmentSelectionSet,
698-
objectType, objectValue, variableValues, path, subsequentPayloads,
699-
deferRecord)}.
713+
- Initialize {resultMap} to an empty ordered map.
714+
- For each {groupedFieldSet} as {responseKey} and {fields}:
715+
- Let {fieldName} be the name of the first entry in {fields}. Note: This
716+
value is unaffected if an alias is used.
717+
- Let {fieldType} be the return type defined for the field {fieldName} of
718+
{objectType}.
719+
- If {fieldType} is defined:
720+
- Let {responseValue} be {ExecuteField(objectType, objectValue, fieldType,
721+
fields, variableValues, path, subsequentPayloads, asyncRecord)}.
722+
- Set {responseValue} as the value for {responseKey} in {resultMap}.
700723
- Append any encountered field errors to {errors}.
701724
- If {parentRecord} is defined:
702725
- Wait for the result of {dataExecution} on {parentRecord}.
703726
- If {errors} is not empty:
704727
- Add an entry to {payload} named `errors` with the value {errors}.
705-
- Add an entry to {payload} named `data` with the value {data}.
728+
- Add an entry to {payload} named `data` with the value {resultMap}.
706729
- Add an entry to {payload} named `label` with the value {label}.
707730
- Add an entry to {payload} named `path` with the value {path}.
708731
- Return {payload}.

0 commit comments

Comments
 (0)