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, orFIELD.
graphql
directive @deprecated(reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUEExample
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
onlocations 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
SchemaDirectiveVisitoror 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.