@@ -419,7 +419,8 @@ fragment directFieldSelectionOnUnion on CatOrDog {
419
419
FieldsInSetCanMerge(set):
420
420
421
421
- 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.
423
424
- Let {spreadsForName} be the set of fragment spreads with a given name in
424
425
{visitedSelections}.
425
426
- Given each pair of members {spreadA} and {spreadB} in {spreadsForName}:
@@ -576,7 +577,7 @@ fragment conflictingDifferingResponses on Pet {
576
577
}
577
578
```
578
579
579
- Fragment arguments can also cause fields to fail to merge.
580
+ Fragment spread arguments can also cause fields to fail to merge.
580
581
581
582
While the following is valid:
582
583
@@ -599,11 +600,11 @@ fragment safeFragmentArguments on Dog {
599
600
```
600
601
601
602
it 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.
605
606
606
- However, by changing the argument values:
607
+ However, by changing the fragment spread argument values:
607
608
608
609
``` graphql counter-example
609
610
fragment conflictingFragmentArguments on Dog {
@@ -706,14 +707,16 @@ validation rules apply in each case.
706
707
707
708
- For each {argument} in the document:
708
709
- 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.
711
714
- {argumentDefinition} must exist.
712
715
713
716
** Explanatory Text**
714
717
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 .
717
720
718
721
For example the following are valid:
719
722
@@ -744,7 +747,7 @@ fragment invalidArgName on Dog {
744
747
}
745
748
```
746
749
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
748
751
` withFragmentArg ` .
749
752
750
753
``` graphql counter-example
@@ -810,10 +813,10 @@ ambiguous and invalid.
810
813
#### Required Arguments
811
814
812
815
- 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 .
817
820
- For each {argumentDefinition} in {argumentDefinitions}:
818
821
- Let {type} be the expected type of {argumentDefinition}.
819
822
- Let {defaultValue} be the default value of {argumentDefinition}.
@@ -1592,18 +1595,18 @@ query ($foo: Boolean = true, $bar: Boolean = false) {
1592
1595
1593
1596
** Formal Specification**
1594
1597
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 }:
1597
1600
- Let {variableName} be the name of {variable}.
1598
1601
- Let {variables} be the set of all variables named {variableName} on
1599
1602
{operation}.
1600
1603
- {variables} must be a set of one.
1601
1604
1602
1605
** Explanatory Text**
1603
1606
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.
1607
1610
1608
1611
``` graphql counter-example
1609
1612
query houseTrainedQuery ($atOtherHomes : Boolean , $atOtherHomes : Boolean ) {
@@ -1632,12 +1635,35 @@ fragment HouseTrainedFragment on Query {
1632
1635
}
1633
1636
```
1634
1637
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
+
1635
1661
### Variables Are Input Types
1636
1662
1637
1663
** Formal Specification**
1638
1664
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 }:
1641
1667
- Let {variableType} be the type of {variable}.
1642
1668
- {IsInputType(variableType)} must be {true}.
1643
1669
@@ -1705,13 +1731,14 @@ query takesCatOrDog($catOrDog: CatOrDog) {
1705
1731
transitively.
1706
1732
- For each {fragment} in {fragments}:
1707
1733
- For each {variableUsage} in scope of {fragment}, variable must be in
1708
- {operation}'s variable list.
1734
+ {fragment}'s or { operation}'s variable list.
1709
1735
1710
1736
** Explanatory Text**
1711
1737
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.
1715
1742
1716
1743
For example:
1717
1744
@@ -1738,9 +1765,10 @@ query variableIsNotDefined {
1738
1765
${atOtherHomes} is not defined by the operation.
1739
1766
1740
1767
Fragments 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.
1744
1772
1745
1773
For example the following is valid:
1746
1774
@@ -1837,7 +1865,7 @@ This is because {houseTrainedQueryTwoNotDefined} does not define a variable
1837
1865
${atOtherHomes} but that variable is used by {isHouseTrainedFragment} which is
1838
1866
included in that operation.
1839
1867
1840
- ### All Variables Used
1868
+ ### All Operation Variables Used
1841
1869
1842
1870
** Formal Specification**
1843
1871
@@ -1945,20 +1973,21 @@ fragment isHouseTrainedFragment on Dog {
1945
1973
This document is not valid because {queryWithExtraVar} defines an extraneous
1946
1974
variable.
1947
1975
1948
- ### All Fragment Arguments Used
1976
+ ### All Fragment Variables Used
1949
1977
1950
1978
** Formal Specification**
1951
1979
1952
1980
- 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
1955
1983
scope.
1956
1984
1957
1985
** Explanatory Text**
1958
1986
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.
1962
1991
1963
1992
For example, the following is invalid:
1964
1993
@@ -1974,10 +2003,10 @@ fragment fragmentArgUnused($atOtherHomes: Boolean) on Dog {
1974
2003
}
1975
2004
```
1976
2005
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 ` .
1981
2010
1982
2011
### All Variable Usages Are Allowed
1983
2012
@@ -1987,9 +2016,9 @@ scope of `fragmentArgUnused`.
1987
2016
- Let {variableUsages} be all usages transitively included in the {operation}.
1988
2017
- For each {variableUsage} in {variableUsages}:
1989
2018
- 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
1993
2022
{variableName} defined within {fragment}.
1994
2023
- Otherwise, let {variableDefinition} be the {VariableDefinition} named
1995
2024
{variableName} defined within {operation}.
0 commit comments