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

如何在Strapi中为GraphQL添加自定义查询以支持按name查询Course?

解决Strapi中GraphQL查询支持name参数的问题

你说得没错,Strapi默认生成的GraphQL course 查询只支持id作为参数,要实现通过name查询,确实需要自定义查询逻辑。下面我给你一步步拆解怎么操作:

1. 编写自定义控制器方法

首先在api/course/controllers/course.js(如果没有就新建这个文件)里添加一个根据name查询课程的方法:

module.exports = {
  // 自定义根据name查询课程的方法
  async findByName(ctx) {
    // 从请求参数里获取name
    const { name } = ctx.params;
    // 调用Strapi的service层查询对应课程
    const course = await strapi.services.course.findOne({ name });
    
    if (!course) {
      return ctx.notFound('Course not found');
    }
    return course;
  },
};

2. 配置对应的API路由

接下来在api/course/config/routes.json(没有则新建)里添加路由映射,让这个控制器方法能被访问到:

{
  "routes": [
    {
      "method": "GET",
      "path": "/courses/name/:name",
      "handler": "course.findByName",
      "config": {
        "policies": []
      }
    }
  ]
}

3. 扩展GraphQL Schema并添加Resolver

现在要让GraphQL识别这个新的查询,需要做两步:

3.1 定义GraphQL查询类型

在api/course/config/schema.graphql(没有则新建)里添加扩展的查询定义:

extend type Query {
  # 定义新的查询,参数name是必填字符串,返回Course类型
  courseByName(name: String!): Course
}

3.2 编写Resolver映射

创建api/course/config/resolver.js文件,把GraphQL查询和控制器方法关联起来:

module.exports = {
  Query: {
    courseByName: async (parent, args, ctx) => {
      // 从GraphQL参数里拿到name
      const { name } = args;
      // 调用我们刚才写的控制器方法
      return await strapi.api.course.controllers.course.findByName({
        params: { name },
      });
    },
  },
};

4. 重启Strapi服务

修改完这些配置和代码后,一定要重启你的Strapi服务,这样新的查询逻辑才能生效。

5. 测试新的GraphQL查询

现在你就可以用新的查询语句来根据name获取课程了:

{
  courseByName(name: "course1") {
    name
    description
    modules {
      title
    }
  }
}

额外选项:修改默认course查询支持name参数

如果你不想新增courseByName查询,而是希望原来的course查询同时支持id和name参数,可以这么做:

  1. 覆盖默认的findOne控制器方法:
module.exports = {
  async findOne(ctx) {
    const { id, name } = ctx.params;
    let query = {};
    
    // 判断传入的是id还是name
    if (id) {
      query = { id };
    } else if (name) {
      query = { name };
    } else {
      return ctx.badRequest('请提供id或name参数');
    }

    const course = await strapi.services.course.findOne(query);
    if (!course) {
      return ctx.notFound('Course not found');
    }
    return course;
  },
};
  1. 修改GraphQL Schema,让course查询接受name参数:
extend type Query {
  course(id: ID, name: String): Course
}

不过这里要注意,因为原来的course查询默认要求id必填,所以修改后要把id设为可选,同时name也设为可选,这样就能支持两种参数查询了。

因为你的name字段设置了unique: true,所以用name查询只会返回唯一结果,这样的设计是完全合理的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 15:02:56