DocumentationDirectives on Directives

Directives on Directive Definitions

GraphQL directives can be applied to directive definitions using the DIRECTIVE_DEFINITION directive location:

directive @tag(name: String!) on DIRECTIVE_DEFINITION
 
directive @cacheControl(maxAge: Int) @tag(name: "runtime") on FIELD_DEFINITION

In GraphQL.js v17, parsing this syntax works by default. In GraphQL.js v16, pass the experimentalDirectivesOnDirectiveDefinitions parser flag.

import { DirectiveLocation } from 'graphql';
 
DirectiveLocation.DIRECTIVE_DEFINITION;

Parser surface

Directive definition directives are represented on the AST:

  • DirectiveDefinitionNode.directives
  • DirectiveExtensionNode.directives
  • Kind.DIRECTIVE_EXTENSION

Parsing this syntax uses the normal parser:

import { parse } from 'graphql';
 
const document = parse(source);

In GraphQL.js v16, enable the parser flag when parsing SDL that uses this syntax:

const document = parse(source, {
  experimentalDirectivesOnDirectiveDefinitions: true,
});

Directive extensions use the same parser behavior:

extend directive @cacheControl @tag(name: "performance")

Runtime schema surface

GraphQL.js does not add a generic GraphQLDirective.directives property. The applied directives remain available through the AST nodes:

  • GraphQLDirective.astNode?.directives
  • GraphQLDirective.extensionASTNodes

GraphQL.js does derive directive deprecation metadata from those AST nodes. GraphQLDirective includes:

  • deprecationReason
  • extensionASTNodes
const directive = schema.getDirective('cacheControl');
 
directive.deprecationReason;
directive.astNode?.directives;
directive.extensionASTNodes;

Deprecating custom directives

@deprecated can be used on directive definitions. The built-in GraphQLDeprecatedDirective includes DIRECTIVE_DEFINITION in its locations.

directive @oldAuth @deprecated(reason: "Use @auth instead") on FIELD_DEFINITION

The introspection type __Directive includes:

  • isDeprecated
  • deprecationReason

__Schema.directives accepts includeDeprecated: Boolean! = false.

query DeprecatedDirectives {
  __schema {
    directives(includeDeprecated: true) {
      name
      isDeprecated
      deprecationReason
    }
  }
}

Directive extensions

Directive extensions can attach deprecation metadata to a directive defined in another document:

directive @oldAuth on FIELD_DEFINITION
 
extend directive @oldAuth @deprecated(reason: "Use @auth instead")

When a schema is extended, GraphQL.js preserves directive extension AST nodes on GraphQLDirective.extensionASTNodes and uses them when computing deprecationReason.

Validation

KnownDirectivesRule understands DIRECTIVE_DEFINITION, so a directive applied to a directive definition must itself be declared for that location.

UniqueDirectivesPerLocationRule also treats a directive definition and its extensions as one directive location for non-repeatable directive uniqueness.