From 27e8bee4f6494b81b5525c8eab14991ce475d185 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Mon, 10 Mar 2025 13:03:56 +0000 Subject: [PATCH 1/6] Consistently use 'response key' not 'response name' --- spec/Section 5 -- Validation.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/Section 5 -- Validation.md b/spec/Section 5 -- Validation.md index 44bc9dbba..100754a92 100644 --- a/spec/Section 5 -- Validation.md +++ b/spec/Section 5 -- Validation.md @@ -418,9 +418,9 @@ fragment directFieldSelectionOnUnion on CatOrDog { FieldsInSetCanMerge(set): -- Let {fieldsForName} be the set of selections with a given response name in - {set} including visiting fragments and inline fragments. -- Given each pair of distinct members {fieldA} and {fieldB} in {fieldsForName}: +- Let {fieldsForKey} be the set of selections with a given response key in {set} + including visiting fragments and inline fragments. +- Given each pair of distinct members {fieldA} and {fieldB} in {fieldsForKey}: - {SameResponseShape(fieldA, fieldB)} must be true. - If the parent types of {fieldA} and {fieldB} are equal or if either is not an Object Type: @@ -450,10 +450,10 @@ SameResponseShape(fieldA, fieldB): - Assert: {typeB} is an object, union or interface type. - Let {mergedSet} be the result of adding the selection set of {fieldA} and the selection set of {fieldB}. -- Let {fieldsForName} be the set of selections with a given response name in +- Let {fieldsForKey} be the set of selections with a given response key in {mergedSet} including visiting fragments and inline fragments. - Given each pair of distinct members {subfieldA} and {subfieldB} in - {fieldsForName}: + {fieldsForKey}: - If {SameResponseShape(subfieldA, subfieldB)} is {false}, return {false}. - Return {true}. @@ -462,13 +462,13 @@ type that is either an Object, Interface or Union type. **Explanatory Text** -If multiple field selections with the same response names are encountered during +If multiple field selections with the same response keys are encountered during execution, the field and arguments to execute and the resulting value should be unambiguous. Therefore any two field selections which might both be encountered for the same object are only valid if they are equivalent. During execution, the simultaneous execution of fields with the same response -name is accomplished by {MergeSelectionSets()} and {CollectFields()}. +key is accomplished by {MergeSelectionSets()} and {CollectFields()}. For simple hand-written GraphQL, this rule is obviously a clear developer error, however nested fragments can make this difficult to detect manually. From 4a15e4a18e1a992c76525cc15522335b6235bbb6 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Mon, 10 Mar 2025 13:05:36 +0000 Subject: [PATCH 2/6] Extract definition of response key from #1039 --- spec/Section 2 -- Language.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/Section 2 -- Language.md b/spec/Section 2 -- Language.md index c2c601fa2..2e0af7218 100644 --- a/spec/Section 2 -- Language.md +++ b/spec/Section 2 -- Language.md @@ -466,8 +466,9 @@ These two operations are semantically identical: Alias : Name : -By default a field's response key in the response object will use that field's -name. However, you can define a different response key by specifying an alias. +:: A _response key_ is the key in the response object which correlates with a +field's result. By default the response key will use the field's name; however, +you can define a different response key by specifying an alias. In this example, we can fetch two profile pictures of different sizes and ensure the resulting response object will not have duplicate keys: From b3cbb5310979c94d3766e07426b4ebcc6cdeeb69 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Mon, 10 Mar 2025 13:07:06 +0000 Subject: [PATCH 3/6] Utilise definition --- spec/Section 5 -- Validation.md | 8 ++++---- spec/Section 6 -- Execution.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/Section 5 -- Validation.md b/spec/Section 5 -- Validation.md index 100754a92..42ecb9c15 100644 --- a/spec/Section 5 -- Validation.md +++ b/spec/Section 5 -- Validation.md @@ -418,8 +418,8 @@ fragment directFieldSelectionOnUnion on CatOrDog { FieldsInSetCanMerge(set): -- Let {fieldsForKey} be the set of selections with a given response key in {set} - including visiting fragments and inline fragments. +- Let {fieldsForKey} be the set of selections with a given _response key_ in + {set} including visiting fragments and inline fragments. - Given each pair of distinct members {fieldA} and {fieldB} in {fieldsForKey}: - {SameResponseShape(fieldA, fieldB)} must be true. - If the parent types of {fieldA} and {fieldB} are equal or if either is not @@ -450,7 +450,7 @@ SameResponseShape(fieldA, fieldB): - Assert: {typeB} is an object, union or interface type. - Let {mergedSet} be the result of adding the selection set of {fieldA} and the selection set of {fieldB}. -- Let {fieldsForKey} be the set of selections with a given response key in +- Let {fieldsForKey} be the set of selections with a given _response key_ in {mergedSet} including visiting fragments and inline fragments. - Given each pair of distinct members {subfieldA} and {subfieldB} in {fieldsForKey}: @@ -462,7 +462,7 @@ type that is either an Object, Interface or Union type. **Explanatory Text** -If multiple field selections with the same response keys are encountered during +If multiple field selections with the same _response key_ are encountered during execution, the field and arguments to execute and the resulting value should be unambiguous. Therefore any two field selections which might both be encountered for the same object are only valid if they are equivalent. diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index d88c685f9..6367cad67 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -491,7 +491,7 @@ A correct executor must generate the following result for that _selection set_: Before execution, the _selection set_ is converted to a grouped field set by calling {CollectFields()}. Each entry in the grouped field set is a list of -fields that share a response key (the alias if defined, otherwise the field +fields that share a _response key_ (the alias if defined, otherwise the field name). This ensures all fields with the same response key (including those in referenced fragments) are executed at the same time. @@ -534,7 +534,7 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments): 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} (the alias if + - Let {responseKey} be the _response key_ of {selection} (the alias if defined, otherwise the field name). - Let {groupForResponseKey} be the list in {groupedFields} for {responseKey}; if no such list exists, create it as an empty list. From 4eaaa4abb4ace1f8bb3a0afbde4a8e9a4b1bc788 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Mon, 10 Mar 2025 13:14:53 +0000 Subject: [PATCH 4/6] response key -> response name --- spec/Section 2 -- Language.md | 6 +++--- spec/Section 5 -- Validation.md | 14 +++++++------- spec/Section 6 -- Execution.md | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/spec/Section 2 -- Language.md b/spec/Section 2 -- Language.md index 2e0af7218..c163ace99 100644 --- a/spec/Section 2 -- Language.md +++ b/spec/Section 2 -- Language.md @@ -466,9 +466,9 @@ These two operations are semantically identical: Alias : Name : -:: A _response key_ is the key in the response object which correlates with a -field's result. By default the response key will use the field's name; however, -you can define a different response key by specifying an alias. +:: A _response name_ is the key in the response object which correlates with a +field's result. By default the response name will use the field's name; however, +you can define a different response name by specifying an alias. In this example, we can fetch two profile pictures of different sizes and ensure the resulting response object will not have duplicate keys: diff --git a/spec/Section 5 -- Validation.md b/spec/Section 5 -- Validation.md index 42ecb9c15..722840400 100644 --- a/spec/Section 5 -- Validation.md +++ b/spec/Section 5 -- Validation.md @@ -418,7 +418,7 @@ fragment directFieldSelectionOnUnion on CatOrDog { FieldsInSetCanMerge(set): -- Let {fieldsForKey} be the set of selections with a given _response key_ in +- Let {fieldsForKey} be the set of selections with a given _response name_ in {set} including visiting fragments and inline fragments. - Given each pair of distinct members {fieldA} and {fieldB} in {fieldsForKey}: - {SameResponseShape(fieldA, fieldB)} must be true. @@ -450,7 +450,7 @@ SameResponseShape(fieldA, fieldB): - Assert: {typeB} is an object, union or interface type. - Let {mergedSet} be the result of adding the selection set of {fieldA} and the selection set of {fieldB}. -- Let {fieldsForKey} be the set of selections with a given _response key_ in +- Let {fieldsForKey} be the set of selections with a given _response name_ in {mergedSet} including visiting fragments and inline fragments. - Given each pair of distinct members {subfieldA} and {subfieldB} in {fieldsForKey}: @@ -462,13 +462,13 @@ type that is either an Object, Interface or Union type. **Explanatory Text** -If multiple field selections with the same _response key_ are encountered during -execution, the field and arguments to execute and the resulting value should be -unambiguous. Therefore any two field selections which might both be encountered -for the same object are only valid if they are equivalent. +If multiple field selections with the same _response name_ are encountered +during execution, the field and arguments to execute and the resulting value +should be unambiguous. Therefore any two field selections which might both be +encountered for the same object are only valid if they are equivalent. During execution, the simultaneous execution of fields with the same response -key is accomplished by {MergeSelectionSets()} and {CollectFields()}. +name is accomplished by {MergeSelectionSets()} and {CollectFields()}. For simple hand-written GraphQL, this rule is obviously a clear developer error, however nested fragments can make this difficult to detect manually. diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index 6367cad67..7b875fa85 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -491,8 +491,8 @@ A correct executor must generate the following result for that _selection set_: Before execution, the _selection set_ is converted to a grouped field set by calling {CollectFields()}. Each entry in the grouped field set is a list of -fields that share a _response key_ (the alias if defined, otherwise the field -name). This ensures all fields with the same response key (including those in +fields that share a _response name_ (the alias if defined, otherwise the field +name). This ensures all fields with the same response name (including those in referenced fragments) are executed at the same time. As an example, collecting the fields of this selection set would collect two @@ -534,7 +534,7 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments): 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} (the alias if + - Let {responseKey} be the _response name_ of {selection} (the alias if defined, otherwise the field name). - Let {groupForResponseKey} be the list in {groupedFields} for {responseKey}; if no such list exists, create it as an empty list. @@ -556,7 +556,7 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments): {CollectFields(objectType, fragmentSelectionSet, variableValues, visitedFragments)}. - For each {fragmentGroup} in {fragmentGroupedFieldSet}: - - Let {responseKey} be the response key shared by all fields in + - Let {responseKey} be the response name 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. @@ -571,7 +571,7 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments): {CollectFields(objectType, fragmentSelectionSet, variableValues, visitedFragments)}. - For each {fragmentGroup} in {fragmentGroupedFieldSet}: - - Let {responseKey} be the response key shared by all fields in + - Let {responseKey} be the response name 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. From 15d7f5c509b60277a98af1ff3f87c304dc8d4b3a Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Mon, 10 Mar 2025 13:18:39 +0000 Subject: [PATCH 5/6] Fix names in algorithms --- spec/Section 5 -- Validation.md | 8 ++++---- spec/Section 6 -- Execution.md | 28 ++++++++++++++-------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/spec/Section 5 -- Validation.md b/spec/Section 5 -- Validation.md index 722840400..1dafc6d71 100644 --- a/spec/Section 5 -- Validation.md +++ b/spec/Section 5 -- Validation.md @@ -418,9 +418,9 @@ fragment directFieldSelectionOnUnion on CatOrDog { FieldsInSetCanMerge(set): -- Let {fieldsForKey} be the set of selections with a given _response name_ in +- Let {fieldsForName} be the set of selections with a given _response name_ in {set} including visiting fragments and inline fragments. -- Given each pair of distinct members {fieldA} and {fieldB} in {fieldsForKey}: +- Given each pair of distinct members {fieldA} and {fieldB} in {fieldsForName}: - {SameResponseShape(fieldA, fieldB)} must be true. - If the parent types of {fieldA} and {fieldB} are equal or if either is not an Object Type: @@ -450,10 +450,10 @@ SameResponseShape(fieldA, fieldB): - Assert: {typeB} is an object, union or interface type. - Let {mergedSet} be the result of adding the selection set of {fieldA} and the selection set of {fieldB}. -- Let {fieldsForKey} be the set of selections with a given _response name_ in +- Let {fieldsForName} be the set of selections with a given _response name_ in {mergedSet} including visiting fragments and inline fragments. - Given each pair of distinct members {subfieldA} and {subfieldB} in - {fieldsForKey}: + {fieldsForName}: - If {SameResponseShape(subfieldA, subfieldB)} is {false}, return {false}. - Return {true}. diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index 7b875fa85..5b960bc15 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -363,7 +363,7 @@ ExecuteSelectionSet(selectionSet, objectType, objectValue, variableValues): - Let {groupedFieldSet} be the result of {CollectFields(objectType, selectionSet, variableValues)}. - Initialize {resultMap} to an empty ordered map. -- For each {groupedFieldSet} as {responseKey} and {fields}: +- For each {groupedFieldSet} as {responseName} and {fields}: - Let {fieldName} be the name of the first entry in {fields}. Note: This value is unaffected if an alias is used. - Let {fieldType} be the return type defined for the field {fieldName} of @@ -371,7 +371,7 @@ ExecuteSelectionSet(selectionSet, objectType, objectValue, variableValues): - If {fieldType} is defined: - Let {responseValue} be {ExecuteField(objectType, objectValue, fieldType, fields, variableValues)}. - - Set {responseValue} as the value for {responseKey} in {resultMap}. + - Set {responseValue} as the value for {responseName} in {resultMap}. - Return {resultMap}. Note: {resultMap} is ordered by which fields appear first in the operation. This @@ -534,11 +534,11 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments): in {variableValues} with the value {true}, continue with the next {selection} in {selectionSet}. - If {selection} is a {Field}: - - Let {responseKey} be the _response name_ of {selection} (the alias if + - Let {responseName} be the _response name_ of {selection} (the alias if defined, otherwise the field name). - - 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}. + - Let {groupForResponseName} be the list in {groupedFields} for + {responseName}; if no such list exists, create it as an empty list. + - Append {selection} to the {groupForResponseName}. - If {selection} is a {FragmentSpread}: - Let {fragmentSpreadName} be the name of {selection}. - If {fragmentSpreadName} is in {visitedFragments}, continue with the next @@ -556,11 +556,11 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments): {CollectFields(objectType, fragmentSelectionSet, variableValues, visitedFragments)}. - For each {fragmentGroup} in {fragmentGroupedFieldSet}: - - Let {responseKey} be the response name shared by all fields in + - Let {responseName} be the response name 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}. + - Let {groupForResponseName} be the list in {groupedFields} for + {responseName}; if no such list exists, create it as an empty list. + - Append all items in {fragmentGroup} to {groupForResponseName}. - If {selection} is an {InlineFragment}: - Let {fragmentType} be the type condition on {selection}. - If {fragmentType} is not {null} and {DoesFragmentTypeApply(objectType, @@ -571,11 +571,11 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments): {CollectFields(objectType, fragmentSelectionSet, variableValues, visitedFragments)}. - For each {fragmentGroup} in {fragmentGroupedFieldSet}: - - Let {responseKey} be the response name shared by all fields in + - Let {responseName} be the response name 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}. + - Let {groupForResponseName} be the list in {groupedFields} for + {responseName}; if no such list exists, create it as an empty list. + - Append all items in {fragmentGroup} to {groupForResponseName}. - Return {groupedFields}. DoesFragmentTypeApply(objectType, fragmentType): From 43310af074e99f5aa06c536aee8bde3f5b1e6095 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Wed, 16 Apr 2025 15:06:43 -1000 Subject: [PATCH 6/6] latest changes --- spec/Section 7 -- Response.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Section 7 -- Response.md b/spec/Section 7 -- Response.md index 6d5ee9b05..037b2a167 100644 --- a/spec/Section 7 -- Response.md +++ b/spec/Section 7 -- Response.md @@ -56,11 +56,11 @@ of a {ExecuteSelectionSet()}, or it is a position in a (potentially nested) List value. Each response position is uniquely identifiable via a _response path_. :: A _response path_ uniquely identifies a _response position_ via a list of -path segments (response keys or list indices) starting at the root of the +path segments (response names or list indices) starting at the root of the response and ending with the associated response position. The value for a _response path_ must be a list of path segments. Path segments -that represent field response keys must be strings, and path segments that +that represent field _response name_ must be strings, and path segments that represent list indices must be 0-indexed integers. If a path segment is associated with an aliased field it must use the aliased name, since it represents a path in the response, not in the request.