Join us for GraphQL Summit, October 10-12 in San Diego. Use promo code ODYSSEY for $400 off your pass.
Docs
Launch GraphOS Studio
Apollo Server 2 is officially deprecated, with end-of-life scheduled for 22 October 2023. Additionally, certain features are end-of-life as of 31 December 2023. Learn more about these deprecations and upgrading.

Directives

Configure GraphQL types, fields, and arguments


A directive decorates part of a GraphQL or with additional configuration. Tools like Apollo Server (and Apollo Client) can read a GraphQL document's s and perform custom logic as appropriate.

s are preceded by the @ character, like so:

schema.graphql
type ExampleType {
oldField: String @deprecated(reason: "Use `newField`.")
newField: String
}

This example shows the @deprecated , which is a default directive (i.e., it's part of the GraphQL specification). It demonstrates the following about s:

  • s can take s of their own (reason in this case).
  • s appear after the declaration of what they decorate (the oldField in this case)

Valid locations

Each can only appear in certain locations within a GraphQL or . These locations are listed in the 's definition.

For example, here's the GraphQL spec's definition of the @deprecated :

directive @deprecated(
reason: String = "No longer supported"
) on FIELD_DEFINITION | ENUM_VALUE

This indicates that @deprecated can decorate either a FIELD_DEFINITION (as shown at the top of the article) or a ENUM_VALUE definition (as shown here):

schema.graphql
enum MyEnum {
OLD_VALUE @deprecated(reason: "Use `NEW_VALUE`.")
NEW_VALUE
}

If @deprecated appears elsewhere in a GraphQL document, it produces an error.

If you create a custom directive, you need to define it (and its valid locations) in your . You don't need to define default directives like @deprecated.

Schema directives vs. operation directives

Usually, a given appears exclusively in GraphQL s or exclusively in GraphQL s (rarely both, although the spec allows this).

For example, among the default directives, @deprecated is a -exclusive and @skip and @include are -exclusive s.

The GraphQL spec lists all possible locations. locations are listed under TypeSystemDirectiveLocation, and locations are listed under ExecutableDirectiveLocation.

Default directives

The GraphQL specification defines the following default s:

DirectiveDescription
@deprecated(reason: String)Marks the schema definition of a field or enum value as deprecated with an optional reason.
@skip(if: Boolean!)If true, the decorated field or fragment in an operation is not resolved by the GraphQL server.
@include(if: Boolean!)If false, the decorated field or fragment in an operation is not resolved by the GraphQL server.

Custom schema directives

You can extend Apollo Server with custom s created by you or a third party.

To learn how to create custom s, see Creating schema directives.

To use a custom :

  1. Make sure the is defined in your with all valid locations listed.

  2. If the uses a SchemaDirectiveVisitor subclass to perform custom logic, provide it to the ApolloServer constructor via the schemaDirectives object.

    The schemaDirectives object maps the name of a directive (e.g., upper) to the subclass that implements its behavior (e.g., UpperCaseDirective).

The following example defines an UpperCaseDirective subclass for use with the @upper custom . Because it's decorated with @upper, the Query.hello returns HELLO WORLD! instead of Hello world!.

const { ApolloServer, gql, SchemaDirectiveVisitor } = require('apollo-server');
const { defaultFieldResolver } = require('graphql');
// Subclass definition for @upper directive logic
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;
};
}
}
// Schema definition (including custom directive)
const typeDefs = gql`
directive @upper on FIELD_DEFINITION
type Query {
hello: String @upper
}
`;
// Resolvers
const resolvers = {
Query: {
hello: (parent, args, context) => {
return 'Hello world!';
},
},
};
// Add directive to the ApolloServer constructor
const server = new ApolloServer({
typeDefs,
resolvers,
schemaDirectives: {
upper: UpperCaseDirective,
}
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`)
});
Previous
Custom scalars
Next
Creating directives
Edit on GitHubEditForumsDiscord