Strapi v4自定义Service覆写find方法:优化查询与分页问题
Strapi v4 优化contact-info服务find方法:单次查询实现嵌套字段填充并保留分页
问题背景
我在使用Strapi v4时,希望获取contact-infos列表时默认填充所有嵌套字段,于是覆写了contact-info服务的find方法。当前代码能实现需求,但会执行两次全量数据库查询;直接返回strapi.entityService的查询结果会触发404错误;如果不调用super.find(),又不知道如何获取分页信息。
原覆写代码:
export default factories.createCoreService('api::contact-info.contact-info', ({ strapi }): {} => ({ async find(...args) { let { results, pagination } = await super.find(...args) results = await strapi.entityService.findMany('api::contact-info.contact-info', { fields: ['locale'], populate: { sections: { populate: { link: true } } } }) return { results, pagination } }, }));
解决方案
核心思路是复用原查询的所有参数(分页、筛选、排序等),在其基础上添加自定义的populate配置,通过strapi.entityService执行单次查询,同时严格按照Strapi核心服务的返回格式返回结果,避免404错误。
修改后的代码:
export default factories.createCoreService('api::contact-info.contact-info', ({ strapi }) => ({ async find(ctx) { // 解构请求传入的所有查询参数:筛选、排序、分页、字段、填充配置 const { filters, sort, pagination, fields, populate } = ctx.params; // 执行单次查询,合并默认参数与自定义填充规则 const { results, pagination: queryPagination } = await strapi.entityService.findMany( 'api::contact-info.contact-info', { filters, sort, pagination, fields: fields || ['locale'], // 保留请求指定字段,无指定则用默认值 populate: { ...populate, // 兼容请求传入的自定义填充,避免覆盖 sections: { populate: { link: true } } } } ); // 按照Strapi核心服务的标准格式返回,避免404 return { data: results, meta: { pagination: queryPagination } }; }, }));
关键说明
- 复用查询参数:直接从
ctx.params中获取筛选、排序、分页等参数,确保与原super.find()的行为一致,无需重复查询数据库 - 兼容自定义填充:通过扩展
populate参数,既保留默认的嵌套字段填充,又不覆盖请求传入的自定义填充配置 - 标准返回格式:Strapi核心服务的
find方法要求返回包含data和meta的结构,直接返回entityService的{results, pagination}会因格式不匹配触发404,转换后即可解决该问题 - 单次查询完成:仅调用一次
entityService.findMany,同时获取带嵌套填充的结果和正确的分页信息
内容的提问来源于stack exchange,提问作者lando
相关产品推荐
相关产品推荐

