Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fragment arguments/variables (syntax/validation/execution) #1081

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 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
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 B -- Grammar Summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,12 @@ Arguments[Const] : ( Argument[?Const]+ )

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

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

InlineFragment : ... TypeCondition? Directives? SelectionSet

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

FragmentName : Name but not `on`

Expand Down
75 changes: 67 additions & 8 deletions spec/Section 2 -- Language.md
Original file line number Diff line number Diff line change
Expand Up @@ -520,10 +520,10 @@ which returns the result:

## Fragments

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

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

FragmentName : Name but not `on`

Expand Down Expand Up @@ -1219,13 +1219,72 @@ 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. Operation-defined variables have global
scope within a given operation. Fragment-defined variables have local scope
within the fragment definition in which they are defined. A variable used within
a fragment must either be declared in each top-level operation that transitively
consumes that fragment, or by that same fragment as a fragment variable
definition. If a variable referenced in a fragment is included by an operation
where neither the fragment nor the operation defines that variable, that
operation is invalid (see
[All Variable Uses Defined](#sec-All-Variable-Uses-Defined)).

## Fragment Variable Definitions

Fragments may define locally scoped variables. This allows fragments to be
reused while enabling 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-defined variable is scoped to the fragment that defines it.
Fragment-defined variables are allowed to shadow operation-defined variables.

```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)
}
```

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 operation-defined
variable, while `dynamicProfilePic` uses the value passed in via the fragment
spread's `size` argument.

## Type References

Type :
Expand Down
Loading
Loading