如何在使用Apollo Express的GraphQL后端中为指定resolver设置中间件
特定Resolver执行中间件的实现方案
在REST API中可以给单条路由绑定中间件,在基于
apollo-express-server的GraphQL服务中,可以通过以下两种常用方案实现仅单个Resolver触发对应中间件的效果:
方案1:高阶函数封装Resolver(无额外依赖)
这个是最简单的实现方式,把中间件逻辑封装为高阶函数,手动包裹需要触发中间件的Resolver即可,和REST路由绑定中间件的逻辑高度一致:
// 自定义中间件逻辑,等价于你示例中的middleAliasApi const middleAliasApi = (targetResolver) => { return async (parent, args, context, info) => { // 这里写Resolver执行前的逻辑:参数校验、上下文修改、权限判断等 console.log('中间件仅在访问getAllTours时触发'); // 执行原有Resolver逻辑 const result = await targetResolver(parent, args, context, info); // 这里可以写Resolver执行后的逻辑:修改返回值、日志上报等 return result; } } // 定义Resolver时仅给需要的字段包裹中间件 const resolvers = { Query: { // 仅getAllTours会触发中间件 getAllTours: middleAliasApi(async (_, args, ctx) => { // 原有Resolver业务逻辑 return await ctx.db.Tour.find(args.filter); }), // 其他Resolver不会触发中间件 getTourById: async (_, { id }, ctx) => { return await ctx.db.Tour.findById(id); } } }
方案2:graphql-middleware批量配置(适合多Resolver场景)
如果需要绑定中间件的Resolver数量较多,可以引入graphql-middleware库做统一匹配管理,无需手动逐个包裹:
安装依赖
npm install graphql-middleware @graphql-tools/schema配置示例
const { ApolloServer } = require('@apollo/server'); const { expressMiddleware } = require('@apollo/server/express4'); const { makeExecutableSchema } = require('@graphql-tools/schema'); const { applyMiddleware } = require('graphql-middleware'); // 定义字段级中间件规则 const tourMiddleware = { Query: { // 仅匹配Query.getAllTours字段 getAllTours: async (resolve, parent, args, context, info) => { // 前置逻辑 const res = await resolve(parent, args, context, info); // 后置逻辑 return res; } } } // 生成可执行Schema并应用中间件 const executableSchema = makeExecutableSchema({ typeDefs, resolvers }); const schemaWithMiddleware = applyMiddleware(executableSchema, tourMiddleware); // 初始化Apollo服务时使用处理后的Schema const server = new ApolloServer({ schema: schemaWithMiddleware });
注意事项
- 不要使用Apollo全局插件/Express全局中间件实现该需求,这类中间件会对所有GraphQL请求生效,无法限定到特定Resolver
- 涉及权限、缓存类的通用逻辑,也可以通过自定义GraphQL指令实现字段级的逻辑注入,效果和中间件一致
内容的提问来源于stack exchange,提问作者parham wolf
相关产品推荐
相关产品推荐

