Field Collection
Before execution, the selection set is converted to a grouped field set by callingCollectFields(). Each entry in the grouped field set is a list of fields that share a response key. This ensures all fields with the same response key (alias or field name) included via referenced fragments are executed at the same time.
As an example, collecting the fields of this selection set would collect two instances of the fielda
and one of fieldb
:
{
a {
subfield1
}
...ExampleFragment
}
fragment ExampleFragment on Query {
a {
subfield2
}
b
}
The depth‐first‐search order of the field groups produced byCollectFields()is maintained through execution, ensuring that fields appear in the executed response in a stable and predictable order.
(
objectType
,
selectionSet
,
variableValues
,
visitedFragments
)
- If visitedFragments if not provided, initialize it to the empty set.
- Initialize groupedFields to an empty ordered map of lists.
- For each
selection
in
selectionSet
:
- If
selection
provides the directive
@skip
, let skipDirective be that directive.- If skipDirective ‘s if argument is true or is a variable in variableValues with the value true , continue with the next selection in selectionSet .
- If
selection
provides the directive
@include
, let includeDirective be that directive.- If includeDirective ‘s if argument is not true and is not a variable in variableValues with the value true , continue with the next selection in selectionSet .
- If
selection
is a
Field
:
- Let responseKey be the response key of selection .
- Let groupForResponseKey be the list in groupedFields for responseKey ; if no such list exists, create it as an empty list.
- Append selection to the groupForResponseKey .
- If
selection
is a
FragmentSpread
:
- Let fragmentSpreadName be the name of selection .
- If fragmentSpreadName is in visitedFragments , continue with the next selection in selectionSet .
- Add fragmentSpreadName to visitedFragments .
- Let fragment be the Fragment in the current Document whose name is fragmentSpreadName .
- If no such fragment exists, continue with the next selection in selectionSet .
- Let fragmentType be the type condition on fragment .
- If DoesFragmentTypeApply ( objectType , fragmentType ) is false, continue with the next selection in selectionSet .
- Let fragmentSelectionSet be the top‐level selection set of fragment .
- Let fragmentGroupedFieldSet be the result of calling CollectFields ( objectType , fragmentSelectionSet , visitedFragments ) .
- For each
fragmentGroup
in
fragmentGroupedFieldSet
:
- Let responseKey be the response key shared by all fields in fragmentGroup
- Let groupForResponseKey be the list in groupedFields for responseKey ; if no such list exists, create it as an empty list.
- Append all items in fragmentGroup to groupForResponseKey .
- If
selection
is an
InlineFragment
:
- Let fragmentType be the type condition on selection .
- If fragmentType is not null and DoesFragmentTypeApply ( objectType , fragmentType ) is false, continue with the next selection in selectionSet .
- Let fragmentSelectionSet be the top‐level selection set of selection .
- Let fragmentGroupedFieldSet be the result of calling CollectFields ( objectType , fragmentSelectionSet , variableValues , visitedFragments ) .
- For each
fragmentGroup
in
fragmentGroupedFieldSet
:
- Let responseKey be the response key shared by all fields in fragmentGroup
- Let groupForResponseKey be the list in groupedFields for responseKey ; if no such list exists, create it as an empty list.
- Append all items in fragmentGroup to groupForResponseKey .
- If
selection
provides the directive
- Return groupedFields .
(
objectType
,
fragmentType
)
- If
fragmentType
is an Object Type:
- if objectType and fragmentType are the same type, return true , otherwise return false .
- If
fragmentType
is an Interface Type:
- if objectType is an implementation of fragmentType , return true otherwise return false .
- If
fragmentType
is a Union:
- if objectType is a possible type of fragmentType , return true otherwise return false .