From ae87499bf3846fb037fee6255d11885582e1e6df Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Fri, 28 Oct 2016 12:27:56 -0700 Subject: [PATCH] [RFC] Add Validation rule for unique directives per location. 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 --- spec/Section 5 -- Validation.md | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/spec/Section 5 -- Validation.md b/spec/Section 5 -- Validation.md index 18d33605d..c0fa0b0d7 100644 --- a/spec/Section 5 -- Validation.md +++ b/spec/Section 5 -- Validation.md @@ -1242,6 +1242,45 @@ query @skip(if: $foo) { ``` +### Directives Are Unique Per Location + +** Formal Specification ** + + * For every {location} in the document for which Directives can apply: + * Let {directives} be the set of Directives which apply to {location}. + * For each {directive} in {directives}: + * Let {directiveName} be the name of {directive}. + * Let {namedDirectives} be the set of all Directives named {directiveName} + in {directives}. + * {namedDirectives} must be a set of one. + +** Explanatory Text ** + +Directives are used to describe some metadata or behavioral change on the +definition they apply to. When more than one directive of the same name is used, +the expected metadata or behavior becomes ambiguous, therefore only one of each +directive is allowed per location. + +For example, the following query will not pass validation because `@skip` has +been used twice for the same field: + +```!graphql +query ($foo: Boolean = true, $bar: Boolean = false) { + field @skip(if: $foo) @skip(if: $bar) +} +``` + +However this example is valid because `@skip` has been used only once per +location, despite being used twice in the query: + +```graphql +query ($foo: Boolean = true, $bar: Boolean = false) { + fieldA @skip(if: $foo) + fieldB @skip(if: $bar) +} +``` + + ## Variables ### Variable Uniqueness