Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
4269caf
RFC: Fragment Arguments
mjmahone Jan 2, 2023
6e91f98
address https://github.com/graphql/graphql-js/pull/3835#discussion_r1…
JoviDeCroock Feb 7, 2024
a868d04
wip
JoviDeCroock Feb 7, 2024
548163a
wording
JoviDeCroock Feb 12, 2024
210a814
corrections
JoviDeCroock Feb 16, 2024
562edd8
Update spec/Section 2 -- Language.md
JoviDeCroock Feb 27, 2024
c46e706
address validation comments
JoviDeCroock Mar 8, 2024
2117038
address language comments
JoviDeCroock Mar 8, 2024
e027a4f
Remove unused `$__UNSET`
JoviDeCroock Mar 26, 2024
2e541bb
Apply Benjie's suggestions
JoviDeCroock Mar 27, 2024
16e8986
conciser validation
JoviDeCroock Mar 27, 2024
8be0561
Apply suggestions from code review
JoviDeCroock Mar 29, 2024
492c556
Apply suggestions from code review
JoviDeCroock Mar 29, 2024
b4f3c5d
formatting and expand examples
JoviDeCroock Mar 30, 2024
f5b3061
add in undefined fragment
JoviDeCroock Mar 30, 2024
df27219
unset instead of null
JoviDeCroock Mar 30, 2024
44aea8b
shorten
JoviDeCroock Mar 30, 2024
61d2117
Apply suggestions from code review
JoviDeCroock May 16, 2024
815952a
remove non standard hyphens
JoviDeCroock May 16, 2024
21e3881
address redundant if
JoviDeCroock May 16, 2024
b60feac
address logical or
JoviDeCroock May 16, 2024
3516ca1
clarify example
JoviDeCroock May 16, 2024
f306736
Ensure variables are defined
JoviDeCroock May 17, 2024
94a0027
fix formatting
JoviDeCroock May 23, 2024
0361664
Update spec/Section 5 -- Validation.md
JoviDeCroock Jun 4, 2024
cbf20d0
Update spec/Section 5 -- Validation.md
JoviDeCroock Jun 6, 2024
b0ac799
wording
JoviDeCroock Jun 8, 2024
7ecdf98
Merge branch 'main' into fragment-args-2024-amendments
JoviDeCroock Jun 8, 2024
4edb481
formatting
JoviDeCroock Jun 9, 2024
5927fa9
Merge branch 'main' into fragment-args-2024-amendments
JoviDeCroock Jun 11, 2024
b07931f
Merge branch 'main' into fragment-args-2024-amendments
JoviDeCroock Aug 8, 2024
641e3d9
update validation
JoviDeCroock Sep 4, 2024
9ef0002
Partial update, rest depends on https://github.com/graphql/graphql-sp…
JoviDeCroock Feb 15, 2025
1bc46cf
Merge branch 'main' into fragment-args-2024-amendments
JoviDeCroock Jul 2, 2025
cbf902b
Fixes
JoviDeCroock Jul 3, 2025
4528738
Merge branch 'main' into fragment-args-2024-amendments
JoviDeCroock Jul 3, 2025
0d7bc1a
Formatting
JoviDeCroock Jul 3, 2025
766e902
Merge branch 'main' into fragment-args-2024-amendments
JoviDeCroock Sep 10, 2025
b617e25
Merge branch 'main' into fragment-args-2024-amendments
JoviDeCroock Oct 7, 2025
185bbac
Merge branch 'main' into fragment-args-2024-amendments
benjie Nov 13, 2025
4805a96
Add missing grammar
benjie Nov 13, 2025
b025653
{operation,fragment}-defined variable -> {operation,fragment} variable
benjie Nov 27, 2025
20fb2f7
Editorial
benjie Nov 27, 2025
276230f
Correct algorithm and provide clarifying note
benjie Nov 27, 2025
6659416
Do not allow merging of fragments referencing different variables
benjie Nov 27, 2025
6536944
Split logic for fragment arguments from directive/field arguments
benjie Nov 27, 2025
7ec40df
Consistency
benjie Nov 27, 2025
fa905f1
Precision and clarity
benjie Nov 27, 2025
ed12965
Add examples and clarify wording/algorithm
benjie Nov 27, 2025
c9cb79d
Spec consistency
benjie Nov 27, 2025
77c44e2
Editorial
benjie Nov 27, 2025
0bcdd92
Editorial
benjie Nov 27, 2025
d4bf325
Fix algorithm mistake
benjie Nov 27, 2025
ef8aaa3
Merge pull request #2 from benjie/fragments-editorial
JoviDeCroock Nov 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions spec/Appendix C -- Grammar Summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,12 @@ Arguments[Const] : ( Argument[?Const]+ )

Argument[Const] : Name : Value[?Const]

FragmentSpread : ... FragmentName Directives?
FragmentSpread : ... FragmentName Arguments? Directives?

InlineFragment : ... TypeCondition? Directives? SelectionSet

FragmentDefinition : Description? fragment FragmentName TypeCondition
Directives? SelectionSet
FragmentDefinition : Description? fragment FragmentName VariablesDefinition?
TypeCondition Directives? SelectionSet

FragmentName : Name but not `on`

Expand Down
89 changes: 77 additions & 12 deletions spec/Section 2 -- Language.md
Original file line number Diff line number Diff line change
Expand Up @@ -578,10 +578,10 @@ which returns the result:

## Fragments

FragmentSpread : ... FragmentName Directives?
FragmentSpread : ... FragmentName Arguments? Directives?

FragmentDefinition : Description? fragment FragmentName TypeCondition
Directives? SelectionSet
FragmentDefinition : Description? fragment FragmentName VariablesDefinition?
TypeCondition Directives? SelectionSet

FragmentName : Name but not `on`

Expand Down Expand Up @@ -1251,10 +1251,15 @@ avoiding costly string building in clients at runtime.
If not defined as constant (for example, in {DefaultValue}), a {Variable} can be
supplied for an input value.

Variables must be defined at the top of an operation and are in scope throughout
the execution of that operation. Values for those variables are provided to a
GraphQL service as part of a request so they may be substituted in during
execution.
:: An _operation variable_ is a variable defined at the top of an operation. An
operation variable is in scope throughout the execution of that operation.
Values for operation variables are provided to a GraphQL service as part of a
request so they may be substituted in during execution.

:: A _fragment variable_ is a variable defined on a fragment. A fragment
variable is locally scoped, it may only be referenced within that fragment
(non-transitively). Values for fragment variables are provided to fragment
spreads.

In this example, we want to fetch a profile picture size based on the size of a
particular device:
Expand Down Expand Up @@ -1283,13 +1288,73 @@ size `60`:

**Variable Use Within Fragments**

Variables can be used within fragments. Variables have global scope with a given
operation, so a variable used within a fragment must be declared in any
top-level operation that transitively consumes that fragment. If a variable is
referenced in a fragment and is included by an operation that does not define
that variable, that operation is invalid (see
Variables can be used within fragments. An _operation variable_ has global scope
within that operation, including within any fragments that operation
transitively consumes. A variable used within a fragment must either be defined
by that fragment, or must be declared in each top-level operation that
transitively consumes that fragment. If a variable referenced in a fragment is
defined in both the fragment and the operation, the fragment definition will be
used. If a variable is referenced in a fragment and is not defined by that
fragment, then any operation that transitively references the fragment and does
not define that variable is invalid (see
[All Variable Uses Defined](#sec-All-Variable-Uses-Defined)).

## Fragment Variable Definitions

Fragments may define locally scoped variables. This allows the caller to specify
the fragment's behavior.

For example, the profile picture may need to be a different size depending on
the parent context:

```graphql example
query userAndFriends {
user(id: 4) {
...dynamicProfilePic(size: 100)
friends(first: 10) {
id
name
...dynamicProfilePic
}
}
}

fragment dynamicProfilePic($size: Int! = 50) on User {
profilePic(size: $size)
}
```

In this case the `user` will have a larger `profilePic` than those found in the
list of `friends`.

A _fragment variable_ is scoped to the fragment that defines it. A fragment
variable may shadow an _operation variable_.

```graphql example
query withShadowedVariables($size: Int!) {
user(id: 4) {
...variableProfilePic
}
secondUser: user(id: 5) {
...dynamicProfilePic(size: 10)
}
}

fragment variableProfilePic on User {
...dynamicProfilePic(size: $size)
}

fragment dynamicProfilePic($size: Int!) on User {
profilePic(size: $size)
}
```

In the example above, the profilePic for `user` will be determined by the
variables set by the operation, while `secondUser` will always have a
`profilePic` of size `10`. In this case, the fragment `variableProfilePic` uses
the value of the _operation variable_, while `dynamicProfilePic` uses the value
of the _fragment variable_ passed in via the fragment spread's `size` argument.

## Type References

Type :
Expand Down
Loading