如何从远程GraphQL Schema中移除所有Mutation?
移除远程GraphQL Schema中所有Mutation类型的解决方案
你遇到的报错是因为FilterRootFields只会移除Mutation下的所有字段,但Mutation根类型本身仍然存在——而GraphQL规范不允许根类型(Query/Mutation/Subscription)没有任何字段,所以抛出了Type Mutation must define one or more fields错误。
要彻底移除所有Mutation,不能只过滤字段,需要直接从Schema中删除Mutation根类型。可以通过mapSchema工具实现,结合FilterRootFields保留指定Query字段,具体代码如下:
代码示例
const { wrapSchema, FilterRootFields, mapSchema, MapperKind } = require('@graphql-tools/wrap'); const filteredRemoteSchema = wrapSchema({ schema: remoteSchema, transforms: [ // 第一步:保留指定的Query字段,过滤掉所有Mutation字段 new FilterRootFields((operation, rootField) => { if (operation === 'Query') { return QUERIES.includes(rootField); } // 过滤所有Mutation字段,保留其他根类型(如Subscription)的字段(按需调整) return operation !== 'Mutation'; }), // 第二步:彻底移除空的Mutation根类型 { transformSchema: (schema) => mapSchema(schema, { [MapperKind.ROOT_OBJECT]: (type) => { // 返回null表示从Schema中移除该根类型 return type.name === 'Mutation' ? null : type; }, }), }, ], });
另一种简洁写法
如果不需要链式使用transform,也可以分两步处理:
const { FilterRootFields, mapSchema, MapperKind } = require('@graphql-tools/wrap'); // 先过滤Query字段,清空Mutation字段 const preFilteredSchema = new FilterRootFields((operation, rootField) => { if (operation === 'Query') { return QUERIES.includes(rootField); } return operation !== 'Mutation'; }).transformSchema(remoteSchema); // 移除Mutation根类型 const finalRemoteSchema = mapSchema(preFilteredSchema, { [MapperKind.ROOT_OBJECT]: (type) => type.name === 'Mutation' ? null : type, });
这样处理后,Schema中就不会存在任何Mutation相关的内容,既符合GraphQL规范,也能满足你保留特定Query并与其他Schema合并的需求。
内容的提问来源于stack exchange,提问作者Nikita Polevoi
相关产品推荐
相关产品推荐

