Custom directives

This is the documentation of the GraphQL Library version 6. For the long-term support (LTS) version 5, refer to GraphQL Library version 5 LTS.

As of @graphql-tools version 8, the mechanism for defining and applying custom directives has changed significantly, and this is reflected in the Neo4j GraphQL Library.

To understand the changes, consider the following example. It works with the implementation of a field directive to uppercase field values, using the following definition:

directive @uppercase on FIELD_DEFINITION

As per the @graphql-tools documentation, a function will be created which returns both the definition and the transformer which provides the behaviour:

function upperDirective(directiveName: string) {
    return {
        upperDirectiveTypeDefs: `directive @${directiveName} on FIELD_DEFINITION`,
        upperDirectiveTransformer: (schema: GraphQLSchema) =>
            mapSchema(schema, {
                [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
                    const fieldDirective = getDirective(schema, fieldConfig, directiveName)?.[0];
                    if (fieldDirective) {
                        const { resolve = defaultFieldResolver } = fieldConfig;
                        fieldConfig.resolve = async (source, args, context, info) => {
                            const result = await resolve(source, args, context, info);
                            if (typeof result === "string") {
                                return result.toUpperCase();
                            }
                            return result;
                        };
                    }
                    return fieldConfig;
                },
            }),
    };
}

On calling the function, the type definition and the transformer returns for the directive:

const { upperDirectiveTypeDefs, upperDirectiveTransformer } = upperDirective("uppercase");

On construction of a Neo4jGraphQL instance, the directive definition can be passed into the typeDefs array alongside the rest of the type definitions:

const neoSchema = new Neo4jGraphQL({
    typeDefs: [
        upperDirectiveTypeDefs,
        `#graphql
            type Movie @node {
                name: String @uppercase
            }
        `,
    ],
    driver,
});

Finally, the Neo4j GraphQL schema must be transformed using the transformer returned from the directive function:

const schema = upperDirectiveTransformer(await neoSchema.getSchema());

Note that this schema object is an instance of a GraphQLSchema which can be used in any GraphQL tools, such as in Apollo Server.