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

如何在Strapi中实现缓存、添加缓存控制头及数据库索引?

Strapi REST API缓存实现与数据库索引优化方案

一、REST API缓存实现(含缓存控制头)

Strapi面板没有直接添加缓存控制头的入口,需通过自定义中间件或服务实现:

1. 全局添加缓存控制头

  • 在src/middlewares/cache-control.js创建中间件文件:
module.exports = (strapi) => {
  return {
    initialize() {
      strapi.app.use(async (ctx, next) => {
        await next();
        // 仅对GET请求设置缓存头,可按需调整缓存时长和规则
        if (ctx.method === 'GET') {
          ctx.set('Cache-Control', 'public, max-age=3600'); // 缓存1小时
        }
      });
    },
  };
};
  • 在config/middleware.js中注册该中间件,确保执行顺序合理:
module.exports = {
  load: {
    before: ['strapi::errors', 'strapi::security'],
    order: ['cache-control', 'strapi::body', 'strapi::session', 'strapi::favicon', 'strapi::public'],
    after: ['strapi::logger', 'strapi::query'],
  },
};

2. 进阶:Redis缓存API响应

针对频繁查询的接口,可实现响应内容缓存,提升性能:

  • 安装Redis依赖:npm install redis
  • 创建缓存服务src/services/cache.service.js:
const redis = require('redis');
const client = redis.createClient({ url: 'redis://localhost:6379' });

client.connect().catch(console.error);

module.exports = ({ strapi }) => ({
  async get(key) {
    const value = await client.get(key);
    return value ? JSON.parse(value) : null;
  },

  async set(key, value, ttl = 3600) {
    await client.setEx(key, ttl, JSON.stringify(value));
  },

  async del(key) {
    await client.del(key);
  },
});
  • 在控制器中使用缓存(以文章列表接口为例,src/api/post/controllers/post.js):
module.exports = {
  async find(ctx) {
    const cacheKey = `posts:${JSON.stringify(ctx.query)}`;
    const cachedData = await strapi.service('cache').get(cacheKey);

    if (cachedData) {
      ctx.body = cachedData;
      return;
    }

    const data = await strapi.entityService.findMany('api::post.post', {
      ...ctx.query,
    });

    await strapi.service('cache').set(cacheKey, data);
    ctx.body = data;
  },
};
  • 注意:在数据创建/更新/删除时,需清理对应缓存,避免返回旧数据。

二、数据库索引添加优化

Strapi无面板操作索引的功能,可通过以下两种方式实现:

1. 模型配置自动生成索引

在模型的schema.json中,给目标字段添加index: true,重启Strapi后会自动在数据库创建索引:

{
  "attributes": {
    "title": {
      "type": "string",
      "index": true // 单字段索引
    },
    "category": {
      "type": "relation",
      "relation": "manyToOne",
      "target": "api::category.category",
      "index": true // 关联字段索引
    }
  }
}

2. 手动创建复合索引

如需多字段组合索引,直接通过数据库客户端执行SQL:

  • PostgreSQL:
CREATE INDEX idx_posts_title_category ON posts (title, category_id);
  • MySQL:
CREATE INDEX idx_posts_title_category ON posts (title, category_id);

索引优化建议

  • 优先给WHERE、JOIN、ORDER BY语句中频繁出现的字段加索引
  • 避免给高频更新的字段添加过多索引,否则会影响写入性能
  • 定期用数据库分析工具(如PostgreSQL的EXPLAIN)排查慢查询,针对性优化索引

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 16:13:36