Skip to content

[validation] Loosen overlapping field validation rules #120

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

Merged
merged 1 commit into from
Nov 13, 2015
Merged
Changes from all commits
Commits
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
60 changes: 35 additions & 25 deletions spec/Section 5 -- Validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,21 +234,24 @@ fragment directFieldSelectionOnUnion on CatOrDog {
** Formal Specification **

* Let {set} be any selection set defined in the GraphQL document
* Let {setForKey} be the set of selections with a given response key in {set}
* All members of {setForKey} must:
* Have identical target fields
* Have identical sets of arguments.
* Have identical sets of directives.
* Let {fieldsForName} be the set of selections with a given response name in
{set} including visiting fragments and inline fragments.
* Given each pair of members {fieldA} and {fieldB} in {fieldsForName}:
* If the parent types of {fieldA} and {fieldB} are equal or if either is not
an Object Type:
* {fieldA} and {fieldB} must have identical field names.
* {fieldA} and {fieldB} must have identical return type.
* {fieldA} and {fieldB} must have identical sets of arguments.

** Explanatory Text **

Selection names are de-duplicated and merged for validation, but the target
field, arguments, and directives must all be identical.
If multiple fields selections with the same response names are encountered
during execution, the result should be unambiguous. Therefore any two field
selections which might both be encountered for the same object are only valid if
they are equivalent.

For human-curated GraphQL, this rules seem a bit counterintuitive since it
appears to be clear developer error. However in the presence of nested
fragments or machine-generated GraphQL, requiring unique selections is a
burdensome limitation on tool authors.
For simple hand-written GraphQL, this rule is obviously a clear developer error,
however nested fragments can make this difficult to detect manually.

The following selections correctly merge:

Expand Down Expand Up @@ -307,26 +310,33 @@ fragment conflictingArgsWithVars on Dog {
doesKnowCommand(dogCommand: $varOne)
doesKnowCommand(dogCommand: $varTwo)
}
```

The same logic applies to directives. The set of directives on each selection
with the same response key in a given scope must be identical.
fragment differingArgs on Dog {
doesKnowCommand(dogCommand: SIT)
doesKnowCommand
}
```

The following is valid:
The following would not merge together, however both cannot be encountered
against the same object:

```graphql
fragment mergeSameFieldsWithSameDirectives on Dog {
name @include(if: true)
name @include(if: true)
fragment safeDifferingFields on Pet {
... on Dog {
name: nickname
}
... on Cat {
name
}
}
```

and the following is invalid:

```!graphql
fragment conflictingDirectiveArgs on Dog {
name @include(if: true)
name @include(if: false)
fragment safeDifferingArgs on Pet {
... on Dog {
doesKnowCommand(dogCommand: SIT)
}
... on Cat {
doesKnowCommand(catCommand: JUMP)
}
}
```

Expand Down