Strapi v4中无法将GraphQL解析器移至单独文件的问题
问题描述
我在论坛上搜遍了Strapi v4自定义GraphQL相关内容,毫无收获。
注意:我的GraphQL技能还处于新手阶段。
我在Strapi v4中扩展了GraphQL解析器,只要解析器和index.ts在同一文件里就能正常工作。我想把GraphQL代码模块化,把解析器移到单独文件,但这么做后一直收到错误:
"resolvers" is defined in the resolver but not in the schema.
以下是嵌入在index.ts里的解析器,完全正常运行:
index.ts
/** * Extend register for GraphQL */ register({ strapi }): void { // customized programmatically using GraphQL's extension const extensionService = strapi.plugin("graphql").service("extension"); const UID = "api::truth-lending-disclosure.truth-lending-disclosure"; extensionService.use(({ strapi }) => ({ typeDefs: ``, resolvers: { Query: { truthLendingDisclosures: async (parent, args, context) => { // toEntityResponse method to allow us to convert our response // to the appropriate format before returning the data. const { toEntityResponseCollection } = strapi .plugin("graphql") .service("format").returnTypes; // define level to populate let _populate = { body: { populate: { section: true, }, }, }; // using shadow CRUD from entity service to fetch data let entities = await strapi.entityService.findMany(UID, { populate: _populate, }); // find and replace placeholder with key-value risCustomerTermDataMap // return the result as JSON string let stringResult = dataSubstitution( JSON.stringify(entities), // convert an object to JSON string risCustomerTermDataMap ); // conver JSON string back object let objectResult = JSON.parse(stringResult); debugger; return toEntityResponseCollection(objectResult); }, }, }, })); },
我把解析器逻辑移到了单独文件mycustom.resolvers.ts:
mycustom.resolvers.ts
import { risCustomerTermDataMap } from "../../../../libs/common/risaCustomerTermDataMap"; import { dataSubstitution } from "../../../../libs/helpers/dataSubstitution"; // the logic in this file does not work with index.ts yet // keep getting "resolvers" define in resolvers, but not in schema. export const resolvers = { Query: { truthLendingDisclosures: async (parent, args, context) => { console.log("***** GraphQL Resolvers*****"); const UID = "api::truth-lending-disclosure.truth-lending-disclosure"; // toEntityResponse method to allow us to convert our response // to the appropriate format before returning the data. const { toEntityResponseCollection } = strapi .plugin("graphql") .service("format").returnTypes; // define level to populate let _populate = { body: { populate: { section: true, }, }, }; // using shadow CRUD from entity service to fetch data let entities = await strapi.entityService.findMany(UID, { populate: _populate, }); // find and replace placeholder with key-value risCustomerTermDataMap // return the result as JSON string let stringResult = dataSubstitution( JSON.stringify(entities), // convert an object to JSON string risCustomerTermDataMap ); // conver JSON string back object let objectResult = JSON.parse(stringResult); debugger; return toEntityResponseCollection(objectResult); }, }, };
我遗漏了什么?
问题根源与修复方案
核心问题
单独文件中的解析器无法直接访问strapi实例——原index.ts中strapi是extensionService.use回调的参数,解析器能直接读取;但移到独立文件后,strapi变量未定义,引发运行时错误,间接触发GraphQL的schema校验报错。
修复步骤
- 修改
mycustom.resolvers.ts,从上下文获取strapi实例
解析器的第三个参数context包含Strapi实例,将代码中所有直接调用的strapi替换为context.strapi:
import { risCustomerTermDataMap } from "../../../../libs/common/risaCustomerTermDataMap"; import { dataSubstitution } from "../../../../libs/helpers/dataSubstitution"; export const resolvers = { Query: { truthLendingDisclosures: async (parent, args, context) => { console.log("***** GraphQL Resolvers*****"); const UID = "api::truth-lending-disclosure.truth-lending-disclosure"; // 从context中获取strapi实例 const { toEntityResponseCollection } = context.strapi .plugin("graphql") .service("format").returnTypes; let _populate = { body: { populate: { section: true, }, }, }; // 使用context.strapi调用entityService let entities = await context.strapi.entityService.findMany(UID, { populate: _populate, }); let stringResult = dataSubstitution( JSON.stringify(entities), risCustomerTermDataMap ); let objectResult = JSON.parse(stringResult); debugger; return toEntityResponseCollection(objectResult); }, }, };
- 在
index.ts中正确导入并使用解析器
确保导入独立文件的resolvers,并在扩展配置中直接引用:
// 导入自定义解析器 import { resolvers } from "./mycustom.resolvers"; /** * Extend register for GraphQL */ register({ strapi }): void { const extensionService = strapi.plugin("graphql").service("extension"); const UID = "api::truth-lending-disclosure.truth-lending-disclosure"; extensionService.use(({ strapi }) => ({ typeDefs: ``, // 使用导入的resolvers resolvers, })); },
- 额外检查(可选)
如果仍报错,确认:
- Strapi的Shadow CRUD已为
truthLendingDisclosures生成对应的schema定义(基于已有内容类型的扩展无需手动添加typeDefs); - 文件导入路径无拼写错误。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

