自定义指令

这是 GraphQL 库版本 6 的文档。有关长期支持 (LTS) 版本 5,请参阅 GraphQL 库版本 5 LTS

@graphql-tools 版本 8 开始,定义和应用自定义指令的机制发生了重大变化,Neo4j GraphQL 库也反映了这一点。

要了解这些变化,请考虑以下示例。它使用以下定义来实现一个字段指令,以将字段值转换为大写

directive @uppercase on FIELD_DEFINITION

根据 @graphql-tools 文档,将创建一个函数,该函数返回定义和变换器,变换器提供行为

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;
                },
            }),
    };
}

调用该函数时,会返回指令的类型定义和变换器

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

在构造 Neo4jGraphQL 实例时,可以将指令定义传递到 typeDefs 数组中,与其他类型定义一起

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

最后,必须使用从指令函数返回的变换器来变换 Neo4j GraphQL 模式

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

请注意,此 schema 对象是 GraphQLSchema 的实例,可以在任何 GraphQL 工具中使用,例如在 Apollo Server 中。