如何重定义Strapi中services.article.find()等数据库方法
Strapi 定位find方法实现及自定义分页逻辑方案
为什么搜不到对应方法
你在业务代码里搜不到find方法的实现是正常的:Strapi默认的控制器、服务方法不是静态写在你项目的业务目录中的,是框架启动时动态从核心依赖包挂载到strapi.services、strapi.controllers对象上的,大部分IDE默认会排除node_modules目录的索引,自然搜不到对应实现。
对应方法的实际存放路径
如果你要查看底层默认实现,可以直接找对应依赖包下的文件,不用全局搜索:
- 集合类型默认服务层find方法(就是你调用的
strapi.services.article.find的默认实现):node_modules/strapi/lib/services/collection-type.js - Mongoose数据库层查询实现(你说的dbrepository层):
node_modules/strapi-connector-mongoose/lib/queries.js,这里面包含了实际拼接mongoose查询、处理_start/_limit分页参数、执行查询的全部逻辑。
自定义分页逻辑的正确实现方式
不要直接修改node_modules下的核心代码,否则下次重新安装依赖、升级Strapi版本时所有修改都会被覆盖。Strapi原生支持在业务目录下覆写默认的服务、控制器方法,直接在你项目的对应api目录下写自定义逻辑即可:
- 打开你项目中
api/article/services/article.js文件,这个文件就是用来覆写article服务默认逻辑的,默认生成时只有空的导出结构。 - 在文件中写入自定义的find方法,处理分页参数后调用底层查询,参考代码如下:
const { sanitizeEntity } = require('strapi-utils'); module.exports = { async find(params) { // 从请求参数中解构分页参数,设置默认值 const { page = 1, pageSize = 10, ...queryParams } = params; // 转换为Strapi底层识别的_start(偏移量)、_limit(单页条数)参数 const formattedParams = { ...queryParams, _start: (Number(page) - 1) * Number(pageSize), _limit: Number(pageSize) }; // 调用底层query方法查询列表 const list = await strapi.query('article').find(formattedParams); // 查询总条数用于分页展示 const total = await strapi.query('article').count(queryParams); // 返回格式化后的结果 return { list: list.map(item => sanitizeEntity(item, { model: strapi.models.article })), pagination: { page: Number(page), pageSize: Number(pageSize), total } }; } };
- 你控制器里的原有代码不需要改动,调用
strapi.services.article.find时会自动优先使用你自定义的覆写方法,不会走默认实现。
其他说明
- 如果你需要修改所有模型通用的数据库查询逻辑,不要直接改mongoose connector的源码,可以通过Strapi的自定义hook、全局中间件的方式扩展query层能力,避免侵入核心依赖。
- 如果需要在IDE中能索引到Strapi核心代码,可以把
node_modules/strapi、node_modules/strapi-connector-mongoose目录加入IDE的索引白名单,后续就能直接跳转对应方法实现了。
内容的提问来源于stack exchange,提问作者user11092881
相关产品推荐
相关产品推荐

