diff --git a/spec/Appendix B -- Grammar Summary.md b/spec/Appendix B -- Grammar Summary.md index a1783c3bc..f17dc2a29 100644 --- a/spec/Appendix B -- Grammar Summary.md +++ b/spec/Appendix B -- Grammar Summary.md @@ -278,7 +278,7 @@ InputObjectTypeExtension : - extend input Name Directives[Const]? InputFieldsDefinition - extend input Name Directives[Const] -DirectiveDefinition : Description? directive @ Name ArgumentsDefinition? on DirectiveLocations +DirectiveDefinition : Description? directive @ Name ArgumentsDefinition? `repeatable`? on DirectiveLocations DirectiveLocations : - `|`? DirectiveLocation diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 00bbb8e49..eec76c966 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -165,7 +165,8 @@ adds additional operation types, or additional directives to an existing schema. Schema extensions have the potential to be invalid if incorrectly defined. 1. The Schema must already be defined. -2. Any directives provided must not already apply to the original Schema. +2. Any non-repeatable directives provided must not already apply to the + original Schema. ## Descriptions @@ -544,7 +545,8 @@ GraphQL tool or service which adds directives to an existing scalar. Scalar type extensions have the potential to be invalid if incorrectly defined. 1. The named type must already be defined and must be a Scalar type. -2. Any directives provided must not already apply to the original Scalar type. +2. Any non-repeatable directives provided must not already apply to the + original Scalar type. ## Objects @@ -934,7 +936,8 @@ Object type extensions have the potential to be invalid if incorrectly defined. may share the same name. 3. Any fields of an Object type extension must not be already defined on the original Object type. -4. Any directives provided must not already apply to the original Object type. +4. Any non-repeatable directives provided must not already apply to the + original Object type. 5. Any interfaces provided must not be already implemented by the original Object type. 6. The resulting extended object type must be a super-set of all interfaces it @@ -1116,7 +1119,8 @@ Interface type extensions have the potential to be invalid if incorrectly define 4. Any Object type which implemented the original Interface type must also be a super-set of the fields of the Interface type extension (which may be due to Object type extension). -5. Any directives provided must not already apply to the original Interface type. +5. Any non-repeatable directives provided must not already apply to the + original Interface type. ## Unions @@ -1239,7 +1243,8 @@ Union type extensions have the potential to be invalid if incorrectly defined. 3. All member types of a Union type extension must be unique. 4. All member types of a Union type extension must not already be a member of the original Union type. -5. Any directives provided must not already apply to the original Union type. +5. Any non-repeatable directives provided must not already apply to the + original Union type. ## Enums @@ -1308,7 +1313,8 @@ Enum type extensions have the potential to be invalid if incorrectly defined. 2. All values of an Enum type extension must be unique. 3. All values of an Enum type extension must not already be a value of the original Enum. -4. Any directives provided must not already apply to the original Enum type. +4. Any non-repeatable directives provided must not already apply to the + original Enum type. ## Input Objects @@ -1437,7 +1443,8 @@ Input object type extensions have the potential to be invalid if incorrectly def 3. All fields of an Input Object type extension must have unique names. 4. All fields of an Input Object type extension must not already be a field of the original Input Object. -5. Any directives provided must not already apply to the original Input Object type. +5. Any non-repeatable directives provided must not already apply to the + original Input Object type. ## List @@ -1606,7 +1613,7 @@ Expected Type | Internal Value | Coerced Result ## Directives -DirectiveDefinition : Description? directive @ Name ArgumentsDefinition? on DirectiveLocations +DirectiveDefinition : Description? directive @ Name ArgumentsDefinition? `repeatable`? on DirectiveLocations DirectiveLocations : - `|`? DirectiveLocation @@ -1685,12 +1692,31 @@ type SomeType { } ``` +A directive may be defined as repeatable by including the "repeatable" keyword. +Repeatable directives are often useful when the same directive should be used +with different arguments at a single location, especially in cases where +additional information needs to be provided to a type or schema extension via +a directive: + +```graphql example +directive @delegateField(name: String!) repeatable on OBJECT | INTERFACE + +type Book @delegateField(name: "pageCount") @delegateField(name: "author") { + id: ID! +} + +extend type Book @delegateField(name: "index") +``` + While defining a directive, it must not reference itself directly or indirectly: ```graphql counter-example directive @invalidExample(arg: String @invalidExample) on ARGUMENT_DEFINITION ``` +Note: The order in which directives appear may be significant, including +repeatable directives. + **Validation** 1. A directive definition must not contain the use of a directive which diff --git a/spec/Section 4 -- Introspection.md b/spec/Section 4 -- Introspection.md index 7990ae11a..35810a000 100644 --- a/spec/Section 4 -- Introspection.md +++ b/spec/Section 4 -- Introspection.md @@ -187,6 +187,7 @@ type __Directive { description: String locations: [__DirectiveLocation!]! args: [__InputValue!]! + isRepeatable: Boolean! } enum __DirectiveLocation { @@ -417,3 +418,5 @@ Fields locations this directive may be placed. * `args` returns a List of `__InputValue` representing the arguments this directive accepts. +* `isRepeatable` must return a Boolean that indicates if the directive may be + used repeatedly at a single location. diff --git a/spec/Section 5 -- Validation.md b/spec/Section 5 -- Validation.md index d53b3e67f..1aefee540 100644 --- a/spec/Section 5 -- Validation.md +++ b/spec/Section 5 -- Validation.md @@ -1440,7 +1440,8 @@ query @skip(if: $foo) { **Formal Specification** * For every {location} in the document for which Directives can apply: - * Let {directives} be the set of Directives which apply to {location}. + * Let {directives} be the set of Directives which apply to {location} and + are not repeatable. * For each {directive} in {directives}: * Let {directiveName} be the name of {directive}. * Let {namedDirectives} be the set of all Directives named {directiveName}