Skip to content

Commit 3fc8a94

Browse files
authored
[RFC] Add Validation rule for unique directives per location. (#229)
This rule was suggested by @jjergus (#223) to remove ambiguity from execution where the `@skip` and `@ignore` directive rules make the assumption that only one is defined per selection. In general I think this assumption should be upheld by valid queries overall, not just for `@skip` and `@include` so that it can be relied upon for any usage of directives. For example, this allows a potential optimization to use a hashmap keyed on directive name to represent the directives at a location rather than an array. Closes #223
1 parent 79caa41 commit 3fc8a94

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

spec/Section 5 -- Validation.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,49 @@ query @skip(if: $foo) {
12421242
```
12431243

12441244

1245+
### Directives Are Unique Per Location
1246+
1247+
** Formal Specification **
1248+
1249+
* For every {location} in the document for which Directives can apply:
1250+
* Let {directives} be the set of Directives which apply to {location}.
1251+
* For each {directive} in {directives}:
1252+
* Let {directiveName} be the name of {directive}.
1253+
* Let {namedDirectives} be the set of all Directives named {directiveName}
1254+
in {directives}.
1255+
* {namedDirectives} must be a set of one.
1256+
1257+
** Explanatory Text **
1258+
1259+
Directives are used to describe some metadata or behavioral change on the
1260+
definition they apply to. When more than one directive of the same name is used,
1261+
the expected metadata or behavior becomes ambiguous, therefore only one of each
1262+
directive is allowed per location.
1263+
1264+
For example, the following query will not pass validation because `@skip` has
1265+
been used twice for the same field:
1266+
1267+
```!graphql
1268+
query ($foo: Boolean = true, $bar: Boolean = false) {
1269+
field @skip(if: $foo) @skip(if: $bar)
1270+
}
1271+
```
1272+
1273+
However the following example is valid because `@skip` has been used only once
1274+
per location, despite being used twice in the query and on the same named field:
1275+
1276+
```graphql
1277+
query ($foo: Boolean = true, $bar: Boolean = false) {
1278+
field @skip(if: $foo) {
1279+
subfieldA
1280+
}
1281+
field @skip(if: $bar) {
1282+
subfieldB
1283+
}
1284+
}
1285+
```
1286+
1287+
12451288
## Variables
12461289

12471290
### Variable Uniqueness

0 commit comments

Comments
 (0)