@@ -419,7 +419,8 @@ fragment directFieldSelectionOnUnion on CatOrDog {
419419FieldsInSetCanMerge(set):
420420
421421- Let {visitedSelections} be the selections in {set} including visiting
422- fragments and inline fragments an applying any supplied fragment arguments.
422+ fragments and inline fragments and applying any supplied fragment spread
423+ arguments.
423424- Let {spreadsForName} be the set of fragment spreads with a given name in
424425 {visitedSelections}.
425426- Given each pair of members {spreadA} and {spreadB} in {spreadsForName}:
@@ -576,7 +577,7 @@ fragment conflictingDifferingResponses on Pet {
576577}
577578```
578579
579- Fragment arguments can also cause fields to fail to merge.
580+ Fragment spread arguments can also cause fields to fail to merge.
580581
581582While the following is valid:
582583
@@ -599,11 +600,11 @@ fragment safeFragmentArguments on Dog {
599600```
600601
601602it is only valid because ` safeFragmentArguments ` uses
602- ` potentiallyConflictingArguments ` with the same value for ` commandOne ` and
603- ` commandTwo ` . Therefore ` commandFragment ` resolves ` doesKnowCommand ` 's
604- ` dogCommand: ` arg to ` SIT ` in both cases.
603+ ` potentiallyConflictingArguments ` with the same value for the fragment-defined
604+ variables ` commandOne ` and ` commandTwo ` . Therefore ` commandFragment ` resolves
605+ ` doesKnowCommand ` 's ` dogCommand ` argument value to ` SIT ` in both cases.
605606
606- However, by changing the argument values:
607+ However, by changing the fragment spread argument values:
607608
608609``` graphql counter-example
609610fragment conflictingFragmentArguments on Dog {
@@ -706,14 +707,16 @@ validation rules apply in each case.
706707
707708- For each {argument} in the document:
708709 - Let {argumentName} be the Name of {argument}.
709- - Let {argumentDefinition} be the argument definition provided by the parent
710- field, fragment definition or directive definition named {argumentName}.
710+ - If the parent is a field or directive:
711+ - Let {argumentDefinition} be the argument or variable definition named
712+ {argumentName} provided by the parent field definition, directive definition
713+ or fragment definition.
711714 - {argumentDefinition} must exist.
712715
713716** Explanatory Text**
714717
715- Every argument provided to a field or directive must be defined in the set of
716- possible arguments of that field or directive .
718+ Every argument provided to a field or directive or fragment spread must be
719+ defined in the set of possible arguments of that field, directive or fragment .
717720
718721For example the following are valid:
719722
@@ -744,7 +747,7 @@ fragment invalidArgName on Dog {
744747}
745748```
746749
747- and this is also invalid as the argument ` dogCommand ` is not defined on fragment
750+ and this is also invalid as the variable ` dogCommand ` is not defined on fragment
748751` withFragmentArg ` .
749752
750753``` graphql counter-example
@@ -810,10 +813,10 @@ ambiguous and invalid.
810813#### Required Arguments
811814
812815- For each Field, Fragment Spread or Directive in the document:
813- - Let {arguments} be the arguments provided by the Field, Fragment Spread or
814- Directive .
815- - Let {argumentDefinitions} be the set of argument definitions of that Field,
816- Fragment Spread or Directive .
816+ - Let {arguments} be the arguments provided by the Field, Directive or
817+ Fragment Spread .
818+ - Let {argumentDefinitions} be the set of argument definitions of that Field
819+ or Directive, or the variable definitions of that Fragment .
817820 - For each {argumentDefinition} in {argumentDefinitions}:
818821 - Let {type} be the expected type of {argumentDefinition}.
819822 - Let {defaultValue} be the default value of {argumentDefinition}.
@@ -1592,18 +1595,18 @@ query ($foo: Boolean = true, $bar: Boolean = false) {
15921595
15931596** Formal Specification**
15941597
1595- - For every {operation} in the document:
1596- - For every {variable} defined on {operation}:
1598+ - For every {operation} and {fragment} in the document:
1599+ - For every {variable} defined on that {operation} or {fragment }:
15971600 - Let {variableName} be the name of {variable}.
15981601 - Let {variables} be the set of all variables named {variableName} on
15991602 {operation}.
16001603 - {variables} must be a set of one.
16011604
16021605** Explanatory Text**
16031606
1604- If any operation defines more than one variable with the same name, it is
1605- ambiguous and invalid. It is invalid even if the type of the duplicate variable
1606- is the same.
1607+ If any operation or fragment defines more than one variable with the same name,
1608+ it is ambiguous and invalid. It is invalid even if the type of the duplicate
1609+ variable is the same.
16071610
16081611``` graphql counter-example
16091612query houseTrainedQuery ($atOtherHomes : Boolean , $atOtherHomes : Boolean ) {
@@ -1632,12 +1635,35 @@ fragment HouseTrainedFragment on Query {
16321635}
16331636```
16341637
1638+ Likewise, it is valid for both an operation and a fragment to define a variable
1639+ with the same name:
1640+
1641+ ``` graphql example
1642+ query C ($atOtherHomes : Boolean ) {
1643+ ... HouseTrainedFragment
1644+ aDog : dog {
1645+ ... HouseTrainedDog
1646+ }
1647+ }
1648+
1649+ fragment HouseTrainedDog ($atOtherHomes : Boolean ) on Dog {
1650+ isHouseTrained (atOtherHomes : $atOtherHomes )
1651+ }
1652+ ```
1653+
1654+ Fragment-defined variables are scoped locally to the fragment that defines them,
1655+ and override any operation-defined variable values, so there is never ambiguity
1656+ about which value to use. In this case, the value of the argument ` atOtherHomes `
1657+ within ` HouseTrainedFragment ` will be the operation-set value, and within
1658+ ` HouseTrainedDog ` will resolve to ` null ` , as the argument is not set by the
1659+ fragment spread in the query ` C ` .
1660+
16351661### Variables Are Input Types
16361662
16371663** Formal Specification**
16381664
1639- - For every {operation} in a {document}:
1640- - For every {variable} on each {operation}:
1665+ - For every {operation} and {fragment} in a {document}:
1666+ - For every {variable} defined on each {operation} or {fragment }:
16411667 - Let {variableType} be the type of {variable}.
16421668 - {IsInputType(variableType)} must be {true}.
16431669
@@ -1705,13 +1731,14 @@ query takesCatOrDog($catOrDog: CatOrDog) {
17051731 transitively.
17061732 - For each {fragment} in {fragments}:
17071733 - For each {variableUsage} in scope of {fragment}, variable must be in
1708- {operation}'s variable list.
1734+ {fragment}'s or { operation}'s variable list.
17091735
17101736** Explanatory Text**
17111737
1712- Variables are scoped on a per-operation basis. That means that any variable used
1713- within the context of an operation must be defined at the top level of that
1714- operation
1738+ Operation-defined Variables are scoped on a per-operation basis, while
1739+ Fragment-defined Variables are scoped locally to the fragment. That means that
1740+ any variable used within the context of an operation must either be defined at
1741+ the top level of that operation or on the fragment that uses that variable.
17151742
17161743For example:
17171744
@@ -1738,9 +1765,10 @@ query variableIsNotDefined {
17381765${atOtherHomes} is not defined by the operation.
17391766
17401767Fragments complicate this rule. Any fragment transitively included by an
1741- operation has access to the variables defined by that operation. Fragments can
1742- appear within multiple operations and therefore variable usages must correspond
1743- to variable definitions in all of those operations.
1768+ operation has access to the variables defined by that operation and defined on
1769+ the fragment. Fragments can appear within multiple operations and therefore
1770+ variable usages not defined on the fragment must correspond to variable
1771+ definitions in all of those operations.
17441772
17451773For example the following is valid:
17461774
@@ -1837,7 +1865,7 @@ This is because {houseTrainedQueryTwoNotDefined} does not define a variable
18371865${atOtherHomes} but that variable is used by {isHouseTrainedFragment} which is
18381866included in that operation.
18391867
1840- ### All Variables Used
1868+ ### All Operation Variables Used
18411869
18421870** Formal Specification**
18431871
@@ -1945,20 +1973,21 @@ fragment isHouseTrainedFragment on Dog {
19451973This document is not valid because {queryWithExtraVar} defines an extraneous
19461974variable.
19471975
1948- ### All Fragment Arguments Used
1976+ ### All Fragment Variables Used
19491977
19501978** Formal Specification**
19511979
19521980- For every {fragment} in the document:
1953- - Let {arguments } be the arguments defined by that {fragment}.
1954- - Each {argument } in {arguments } must be used at least once in the fragment's
1981+ - Let {variables } be the variables defined by that {fragment}.
1982+ - Each {variable } in {variables } must be used at least once in the fragment's
19551983 scope.
19561984
19571985** Explanatory Text**
19581986
1959- All arguments defined by a fragment must be used in that same fragment. Because
1960- fragment arguments are scoped to the fragment they are defined on, if the
1961- fragment does not use the argument, then the argument is superfluous.
1987+ All variables defined by a fragment must be used in that same fragment. Because
1988+ fragment-defined variables are scoped to the fragment they are defined on, if
1989+ the fragment does not use the variable, then the variable definition is
1990+ superfluous.
19621991
19631992For example, the following is invalid:
19641993
@@ -1974,10 +2003,10 @@ fragment fragmentArgUnused($atOtherHomes: Boolean) on Dog {
19742003}
19752004```
19762005
1977- This document is invalid because even though ` fragmentArgUnused ` is spread with
1978- the argument ` atOtherHomes ` , and even though ` $atOtherHomes ` is defined as an
1979- operation variable, there is never a variable ` $atOtherHomes ` used within the
1980- scope of ` fragmentArgUnused ` .
2006+ This document is invalid: even though ` fragmentArgUnused ` is spread with the
2007+ argument ` atOtherHomes ` and ` $atOtherHomes ` is defined as an operation variable,
2008+ there is never a variable ` $atOtherHomes ` used within the scope of
2009+ ` fragmentArgUnused ` .
19812010
19822011### All Variable Usages Are Allowed
19832012
@@ -1987,9 +2016,9 @@ scope of `fragmentArgUnused`.
19872016 - Let {variableUsages} be all usages transitively included in the {operation}.
19882017 - For each {variableUsage} in {variableUsages}:
19892018 - Let {variableName} be the name of {variableUsage}.
1990- - If the usage is within a {fragment} that defines an argument of
1991- {variableName}:
1992- - Let {variableDefinition} be the {ArgumentDefinition } named
2019+ - If the usage is within a {fragment} that defines a {variableDefinition}
2020+ for {variableName}:
2021+ - Let {variableDefinition} be the {VariableDefinition } named
19932022 {variableName} defined within {fragment}.
19942023 - Otherwise, let {variableDefinition} be the {VariableDefinition} named
19952024 {variableName} defined within {operation}.
0 commit comments