缓存
@nestjs/cache-manager 统一缓存 API,存储实现可插拔。
NestJS 的缓存模块是通过 @nestjs/cache-manager 包来实现的,它为应用带来了一个简单统一的 API,底层支持多种性能出色的缓存存储方案,并可以灵活配置。
模块导入与基础配置
要开始使用缓存,首先需要安装 @nestjs/cache-manager 核心包和 cache-manager 存储驱动:
npm install @nestjs/cache-manager cache-manager
安装完成后,在模块(例如 AppModule)中通过 .register() 方法导入并配置 CacheModule,最基础的内存缓存开启方式如下:
// app.module.ts
import { Module } from "@nestjs/common";
import { CacheModule } from "@nestjs/cache-manager";
@Module({
imports: [
CacheModule.register({
ttl: 60000, // 设置全局缓存过期时间为 60 秒(单位:毫秒)
max: 100, // 设置内存缓存中最大存储的项数为 100
isGlobal: true, // 设为全局,避免在每个模块重复导入
}),
],
})
export class AppModule {}
⚠️ 特别提醒:在使用 cache-manager v5 或更高版本时,ttl 的单位是毫秒 (milliseconds), 而旧版 v4 使用的是秒 (seconds)。需要仔细核对所使用的库版本。
💾 存储引擎:内存 vs. Redis
@nestjs/cache-manager 默认提供内存缓存,它可以直接将数据存储在应用进程中,适用于单机或中小规模的场景。但对于需要跨实例共享缓存的分布式系统,则必须选择像 Redis 这样的集中式存储。
使用 Redis 时,需要额外安装驱动包并调整配置:
npm install cache-manager-redis-yet
然后在 CacheModule 中配置 store 和连接参数:
// app.module.ts
import { Module } from "@nestjs/common";
import { CacheModule } from "@nestjs/cache-manager";
import { redisStore } from "cache-manager-redis-yet";
@Module({
imports: [
CacheModule.registerAsync({
useFactory: async () => ({
store: await redisStore({
socket: {
host: "localhost",
port: 6379,
},
password: "your-password",
ttl: 60000, // 基于 Redis 的 TTL
}),
}),
}),
],
})
export class AppModule {}
🛠️ 与缓存实例交互
在某些复杂场景下,你可能需要直接操作缓存。通过 CACHE_MANAGER 这个 token 就可以注入 Cache 实例,进而对缓存进行精细化的控制。
// your.service.ts
import { Injectable, Inject } from "@nestjs/common";
import { CACHE_MANAGER } from "@nestjs/cache-manager";
import { Cache } from "cache-manager";
@Injectable()
export class YourService {
constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
async getValue(key: string) {
// 获取缓存,若不存在则返回 null
const value = await this.cacheManager.get(key);
// 手动设置缓存,第三个参数可指定该键的 TTL(单位:毫秒)
await this.cacheManager.set(key, { value: "cached data" }, 1000);
// 删除单个键
await this.cacheManager.del(key);
// 清空整个缓存(请谨慎使用)
await this.cacheManager.reset();
}
}
🧩 自动缓存响应 (CacheInterceptor)
若只需对 GET 请求进行缓存,使用 CacheInterceptor 是最简洁的方案。它将自动拦截响应并将其存入缓存。你可以将其应用到控制器层(作用于所有路由)或方法层。
// app.controller.ts
import { Controller, Get, UseInterceptors } from "@nestjs/common";
import { CacheInterceptor } from "@nestjs/cache-manager";
@Controller()
@UseInterceptors(CacheInterceptor)
export class AppController {
@Get()
findAll(): string[] {
return []; // 此响应将被自动缓存
}
}
🎨 自定义缓存键 (CacheKey) 与 TTL (CacheTTL)
CacheInterceptor 默认会根据路由生成缓存键,例如 GET /users。如果需要更精细的控制,可以使用 @CacheKey() 和 @CacheTTL() 装饰器。
import { CacheKey, CacheTTL } from '@nestjs/cache-manager';
@Get()
@CacheKey('custom_key_for_findAll')
@CacheTTL(120000) // 覆盖全局设置,将此接口的缓存时间设为 120 秒
findAll(): string[] {
return [];
}
🌐 全局缓存配置
如果你希望缓存拦截器默认作用于所有路由,可以在模块配置中将其声明为全局拦截器,但也需要注意对 WebSocket 或非 GET 请求等场景的处理。
// app.module.ts
import { Module } from "@nestjs/common";
import { APP_INTERCEPTOR } from "@nestjs/core";
import { CacheInterceptor } from "@nestjs/cache-manager";
@Module({
providers: [
{
provide: APP_INTERCEPTOR,
useClass: CacheInterceptor,
},
],
})
export class AppModule {}
高级用法与最佳实践
- 缓存一致性:当数据变更(如数据库的增、删、改操作)时,确保同时删除或更新对应的缓存。一种常见的模式是在
@Put(),@Post(),@Delete()等会修改数据的操作中,调用this.cacheManager.del(key)。 - 访问控制:避免在需要验证用户权限、需要返回动态内容(如需要
@Res()直接操作响应)、或 GraphQL 解析器等场景中使用CacheInterceptor。 - 数据类型限制:内存缓存只能存储符合 结构化克隆算法 支持的类型,如基本类型和普通对象。这意味着像
Date对象、Set、Map等高级对象的缓存可能会遇到问题。
总结
| 核心概念 | 实现关键点 |
|---|---|
| 模块注册 | 使用 CacheModule.register() 进行基础配置;使用 CacheModule.registerAsync() 实现更灵活的动态配置。 |
| 存储选择 | 默认内存,适合开发;上生产或分布式场景需用 Redis,推荐 cache-manager-redis-yet 驱动。 |
| 自动缓存 | 通过 @UseInterceptors(CacheInterceptor) 实现,简单高效。 |
| 精细控制 | 通过 @CacheKey() 和 @CacheTTL() 自定义键值与过期时间,满足特殊场景需求。 |
| 手动控制 | 通过 @Inject(CACHE_MANAGER) 获得 Cache 实例,实现更灵活的存取、删除等精细操作。 |
| 最佳实践:缓存失效 | 在数据更新时务必同步删除或更新缓存,以保障数据一致性。 |
希望这份介绍能帮助你系统了解并快速上手 NestJS 的缓存功能。如果希望继续了解某个部分更具体的用法,也可以告诉我~
参考文献
以下链接在编写时均可正常访问:
| 资料 | 说明 |
|---|---|
| NestJS 文档 | 官方 |
| Caching | 本章主题 |
| Request lifecycle | 执行顺序 |
相关文章
认证与授权
认证(Authentication):确认「你是谁」(如 JWT、Session)。 - 授权(Authorization):确认「你能做什么」(如 RBAC、策略检查)。
提供者与服务
Service 是最常见的 Provider,封装业务逻辑。见 module。
守卫 (Guards) 与授权
守卫决定是否放行请求,常用于认证与授权。见 auth。
配置管理(Config 模块)
@nestjs/config 加载 .env 并提供 ConfigService。见 工程化 env。
数据库集成(以 TypeORM 为例)
Nest 通过 @nestjs/typeorm 等包集成 ORM;生产环境用 migration,慎用 synchronize。亦可选用 Prisma、MikroORM 等(见 官方 Database)。
定时任务
@nestjs/schedule 基于 cron 表达式调度任务。
Series
new
3 / 19