Graphql
字段中间件
学习如何在 NestJS GraphQL 中使用字段中间件来拦截和修改字段解析过程。
字段中间件
本章仅适用于代码优先方法。
字段中间件允许您在字段解析之前和之后运行任意代码,这允许您转换参数、结果,甚至完全控制字段解析。
让我们创建一个简单的中间件,将字段的字符串值转换为大写:
import { FieldMiddleware, MiddlewareContext, NextFn } from '@nestjs/graphql';
const loggerMiddleware: FieldMiddleware = async (
ctx: MiddlewareContext,
next: NextFn,
) => {
const value = await next();
console.log(value);
return value;
};
MiddlewareContext 是一个包装器,围绕 GraphQL 解析器参数({ source, args, context, info }),而 NextFn 表示下一个中间件(在堆栈中)或实际字段解析器。
现在,让我们将此中间件应用到 name 字段:
@ObjectType()
export class Recipe {
@Field({ middleware: [loggerMiddleware] })
name: string;
}
现在,每当我们请求 name 字段时,其值将记录到控制台。
您还可以将中间件应用到自定义字段解析器(使用 @ResolveField() 装饰器注册的方法):
@Resolver(() => Recipe)
export class RecipeResolver {
@ResolveField(() => String, { middleware: [loggerMiddleware] })
name(@Parent() recipe: Recipe): string {
return recipe.name;
}
}
同样,您可以将中间件应用到查询/变更处理程序:
@Resolver(() => Recipe)
export class RecipeResolver {
@Query(() => Recipe, { middleware: [loggerMiddleware] })
recipe(): Recipe {
return new Recipe();
}
}
多个中间件
要将多个中间件绑定到单个字段,只需将它们传递给 middleware 数组。中间件的执行顺序与数组中的顺序相同(从左到右)。
@ObjectType()
export class Recipe {
@Field({ middleware: [loggerMiddleware, uppercaseMiddleware] })
name: string;
}
全局中间件
除了将中间件绑定到特定字段外,您还可以注册一个或多个全局运行的中间件(它们将在每个字段之前执行)。
GraphQLModule.forRoot({
autoSchemaFile: 'schema.gql',
fieldResolverEnhancers: ['middleware'],
buildSchemaOptions: {
fieldMiddleware: [loggerMiddleware],
},
}),
fieldResolverEnhancers 选项允许您控制哪些增强器应该为字段解析器运行(不是根级别查询/变更/订阅处理程序)。可用的增强器有:guards(守卫)、interceptors(拦截器)、filters(过滤器)和 middleware(中间件)。