0
0
GraphqlHow-ToBeginner · 4 min read

How to Create Custom Directive in GraphQL: Syntax and Example

To create a custom directive in GraphQL, define it in your schema using the directive @name(args) on LOCATION syntax, then implement its logic in your server code. Custom directives let you add reusable behavior to your schema fields or types.
📐

Syntax

A custom directive in GraphQL is declared using the directive keyword followed by the directive name, optional arguments, and the locations where it can be applied.

  • directive @name(args) on LOCATION: Defines the directive.
  • @name: The directive's name used in schema or queries.
  • args: Optional input arguments for the directive.
  • LOCATION: Places where the directive can be used, like FIELD_DEFINITION, OBJECT, or FIELD.
graphql
directive @deprecated(reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE
💻

Example

This example shows how to create a custom directive @upper that converts a string field's result to uppercase. It includes the schema definition and a simple resolver implementation in JavaScript using Apollo Server.

javascript
const { ApolloServer, gql, SchemaDirectiveVisitor } = require('apollo-server');
const { defaultFieldResolver } = require('graphql');

// Schema with custom directive definition
const typeDefs = gql`
  directive @upper on FIELD_DEFINITION

  type Query {
    hello: String @upper
  }
`;

// Directive implementation
class UpperCaseDirective extends SchemaDirectiveVisitor {
  visitFieldDefinition(field) {
    const { resolve = defaultFieldResolver } = field;
    field.resolve = async function (...args) {
      const result = await resolve.apply(this, args);
      if (typeof result === 'string') {
        return result.toUpperCase();
      }
      return result;
    };
  }
}

// Resolvers
const resolvers = {
  Query: {
    hello: () => 'hello world'
  }
};

// Server setup
const server = new ApolloServer({
  typeDefs,
  resolvers,
  schemaDirectives: {
    upper: UpperCaseDirective
  }
});

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});
Output
Server ready at http://localhost:4000/ Query example: { hello } Response: { "data": { "hello": "HELLO WORLD" } }
⚠️

Common Pitfalls

Common mistakes when creating custom directives include:

  • Not specifying correct on locations in the directive definition, causing it to be unusable where intended.
  • Forgetting to implement the directive logic in the server, so the directive has no effect.
  • Using synchronous resolver overrides without handling async results properly.
  • Applying directives in schema places not supported by the directive definition.

Always test your directive with queries to ensure it behaves as expected.

graphql
/* Wrong: Directive defined only on OBJECT but used on FIELD_DEFINITION */
directive @example on OBJECT

/* Right: Directive defined on FIELD_DEFINITION to use on fields */
directive @example on FIELD_DEFINITION
📊

Quick Reference

Summary tips for creating custom directives:

  • Define directive with directive @name(args) on LOCATION.
  • Implement directive logic in server code by extending SchemaDirectiveVisitor or equivalent.
  • Use directive locations like FIELD_DEFINITION, OBJECT, FIELD, etc.
  • Test directives with queries to verify behavior.
  • Remember directives can modify schema or query execution.

Key Takeaways

Define custom directives in your GraphQL schema with the directive keyword and specify locations.
Implement directive behavior in your server code to modify field resolution or schema behavior.
Use correct directive locations to avoid errors when applying directives.
Test your directives with queries to ensure they work as intended.
Custom directives add reusable, declarative behavior to your GraphQL API.