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

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校验报错。

修复步骤

  1. 修改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);
    },
  },
};
  1. 在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,
  }));
},
  1. 额外检查(可选)
    如果仍报错,确认:
  • Strapi的Shadow CRUD已为truthLendingDisclosures生成对应的schema定义(基于已有内容类型的扩展无需手动添加typeDefs);
  • 文件导入路径无拼写错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 08:45:37