You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

配置Node.js Apollo Server的Context时如何识别当前请求的mutation

Apollo Server 按Mutation动态配置Context的高效实现方案

最优方案:复用Apollo内置解析能力(无重复解析开销)

不需要自行解析请求体的Query,直接通过Apollo的插件钩子拿到已经解析完成的操作信息,完全避免重复解析,也不需要处理嵌套的AST结构,实现逻辑如下:

  • 初始化Context时预留存储操作信息的字段
  • 通过didResolveOperation插件钩子获取Apollo解析完成的操作结果,直接修改当前请求的Context即可

代码示例(Apollo Server 4):

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';

const server = new ApolloServer({
  typeDefs,
  resolvers,
  // 初始化基础Context
  context: async ({ req }) => {
    return {
      req,
      currentOperation: null,
      // 其他通用Context字段
    };
  },
  plugins: [
    {
      async requestDidStart() {
        return {
          // 该钩子在Apollo完成Query解析、确定操作类型后触发
          async didResolveOperation(requestContext) {
            const { operation, contextValue } = requestContext;
            // 直接获取结构化的操作信息,无需自行处理AST
            const operationType = operation.operation; // 返回 query / mutation / subscription
            const operationName = operation.selectionSet.selections[0].name.value;

            // 写入Context
            contextValue.currentOperation = {
              type: operationType,
              name: operationName
            };

            // 在这里添加你的条件逻辑
            if (operationType === 'mutation' && operationName === 'createUser') {
              // 比如给特定Mutation跳过权限校验
              contextValue.skipAuth = true;
            }
          }
        };
      }
    }
  ]
});

该方案是性能最优的实现,完全复用Apollo本身的解析结果,没有额外开销,支持所有复杂Query场景,适配Apollo Server 3/4所有版本。

轻量场景可选方案

方案1:Resolver直接取Info字段

如果不需要在全局Context初始化阶段使用Mutation信息,仅单个Resolver需要判断,直接取Resolver的第四个参数info即可,无需额外配置:

const resolvers = {
  Mutation: {
    updateUser: async (parent, args, context, info) => {
      const isMutation = info.operation.operation === 'mutation';
      const mutationName = info.operation.name?.value;
      // 你的业务逻辑
    }
  }
};

方案2:正则快速匹配(简单场景)

如果业务场景的Query结构简单,没有多操作、别名、注释等复杂情况,可以用正则快速匹配Mutation名称,性能损耗几乎可以忽略:

context: async ({ req }) => {
  const query = req.body.query || '';
  // 匹配Mutation后的第一个操作名
  const mutationMatch = query.match(/mutation\s+(\w+)/);
  const currentMutation = mutationMatch ? mutationMatch[1] : null;
  return {
    currentMutation,
    // 其他逻辑
  };
}

该方案仅适合简单业务场景,复杂Query可能出现匹配误差。

内容的提问来源于stack exchange,提问作者Sihoon Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 12:27:03