在本教程中,我们将与Nestjs和Redis一起探索缓存的世界。
在我们深入介入Redis之前,Nestjs提供了可以用作内存数据存储的内存中缓存 redis。
为了开始,您可以为此构造此github repository。请确保您选择基本分支,因为它包含本教程的基本应用程序设置。
设置基本应用程序设置后,您可以继续安装cache-manager
软件包及其依赖项。
npm install @nestjs/cache-manager cache-manager
,如果您熟悉Nestjs内存中缓存实现,则当前对Cache-Manager有一个更新,我们在本教程中使用版本5。与版本4相反,版本5现在提供 ttl(寿命),以毫秒提供。我们必须进行转换,然后将其解析为Nestjs,因为Nestjs不为我们进行转换。
要启用缓存,我们必须将CacheModule
导入到app.module.ts
文件中。
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '@nestjs/mongoose';
import { ContactModule } from './contact/contact.module';
import { CacheModule } from '@nestjs/cache-manager';
@Module({
imports: [
// mongodb://127.0.0.1:27017/nest-redis - use env variables or other secure options in production
MongooseModule.forRoot('mongodb://127.0.0.1:27017/nest-redis', {
useNewUrlParser: true,
}), ContactModule,
CacheModule.register(),
], controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
我们的app.module.ts
文件应该看起来像上面的文件。
我们还将将其导入我们的Contact
模块。在Nestjs中的任何功能模块中,都需要分别将cache-manager
导入其中。如果您有一个不需要缓存的模块,那么这不是必需的。
我们的contact.module.ts
应该类似于下面的代码块:
import { Module } from '@nestjs/common';
import { ContactService } from './contact.service';
import { ContactController } from './contact.controller';
import { MongooseModule } from '@nestjs/mongoose';
import { ContactSchema } from './schemas/schema';
import { CacheModule } from '@nestjs/cache-manager';
@Module({
imports: [
MongooseModule.forFeature([{ name: 'Contact', schema: ContactSchema }]),
CacheModule.register(),
], providers: [ContactService],
controllers: [ContactController],
})
export class ContactModule {}
一个很好的替代方法是为 cachemodule.register()设置isGlobal
选项。如果您需要在所有模块上进行缓存可用性,则可以考虑此选项。
让我们继续前往我们的Contact controller
,以修改我们现有的一些终点。对于@Get('contacts/:contactId')
端点,我们要在调用该方法之前检查我们的response
是否在缓存中。使用@useInterceptors
装饰器可以实现:
我们的getContact
方法应与以下相似:
@UseInterceptors(CacheInterceptor) // Automatically cache the response for this endpoint
@Get('contacts/:contactId')
async getContact(
@Res() res,
@Param('contactId') contactId,
) {
const contact = await this.contactService.getContact(contactId);
if (!contact) throw new NotFoundException('Contact does not exist');
return res.status(HttpStatus.OK).json(contact);
}
要注意的事情:
- 到期时间为5秒
- 拦截器根据路由路径为缓存条目的缓存键自动化。 这两个选项都可以有效地控制并超越。
实施替代,我们的getContact
将是:
@UseInterceptors(CacheInterceptor) // Automatically cache the response for this endpoint
@CacheKey('getcontact-key')
@CacheTTL(60000) // now in milliseconds (1 minute === 60000)
@Get('contacts/:contactId')
async getContact(
@Res() res,
@Param('contactId') contactId,
) {
const contact = await this.contactService.getContact(contactId);
if (!contact) throw new NotFoundException('Contact does not exist');
return res.status(HttpStatus.OK).json(contact);
}
- 根据官方的Nestjs文档,Cachemodule将无法与GraphQl应用程序正确使用*
现在redis
根据the official Redis website,Redis是开源,内存数据结构存储,用作数据库,缓存,消息代理和流引擎。
从Redis进行了调查
要使用redis而不是内存缓存,我们需要安装相关的软件包:
npm i --save cache-manager-redis-yet
此软件包是用于将配置传递给node_redis
软件包的nestjs
包装器。现在,我们可以更改app.module.ts
的某些配置以使用redis。
注意:暂停了cache-manager-redis-store
,以允许我们刚安装的软件包。我们安装的此package
是tracked directly by the koude19 team。
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '@nestjs/mongoose';
import { ContactModule } from './contact/contact.module';
import { CacheModule } from '@nestjs/cache-manager';
import { redisStore } from 'cache-manager-redis-yet';
@Module({
imports: [
MongooseModule.forRoot('mongodb://127.0.0.1:27017/nest-redis', {
useNewUrlParser: true,
}),
CacheModule.registerAsync({
isGlobal: true,
useFactory: async () => ({
store: await redisStore({
socket: {
host: 'localhost',
port: 6379,
},
}),
}),
}),
ContactModule,
], controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
这使我们能够添加新的config options
:
REDISSTORE:代表node-cache-manager-redis-yet
我们刚刚安装
主机和端口设置为默认值
,您还没有运行REDIS服务器,您可以为操作系统查找各种安装方法或考虑Docker选项
前往我们的contact.controller
页面,我们可以配置我们的getContact
方法,以检查在查询主数据库之前是否有一个缓存的数据。如果存在,我们想返回其他我们想在查询数据库后设置它。
我们的getContact
应该与以下相似:
@Get('contacts/:contactId')
async getContact(@Res() res, @Param('contactId') contactId) {
const cachedData = await this.cacheService.get(contactId.toString());
if (cachedData) {
console.log('Getting data from cache');
return res.status(HttpStatus.OK).json(cachedData);
}
const contact = await this.contactService.getContact(contactId);
if (!contact) throw new NotFoundException('Contact does not exist');
await this.cacheService.set(contactId.toString(), contact);
const newCachedData = await this.cacheService.get(contactId.toString());
console.log('data set to cache', newCachedData);
return res.status(HttpStatus.OK).json(contact);
}
让我们简要介绍上述代码块:
const cachedData = await this.cacheService.get(contactId.toString());
if (cachedData) {
console.log('Getting data from cache');
return res.status(HttpStatus.OK).json(cachedData);
}
cachedData
变量正在检查我们是否有现有缓存,如果存在,则可以检查记录器,并且您将获得从cache 。
获取数据
await this.cacheService.set(contactId.toString(), contact);
const newCachedData = await this.cacheService.get(contactId.toString());
console.log('data set to cache', newCachedData);
如果我们的数据在缓存中不存在,则上面的代码块可以帮助我们设置在缓存中。
您的缓存数据现在将持续到您的本地redis服务器。
您可以测试端点,您应该得到与我在记录器中输出相似的结果:
[Nest] 3720 - 05/09/2023, 10:00:49 AM LOG [NestApplication] Nest application successfully started +5ms
data set to cache {
_id: '6459510cfc398baa01998a66',
first_name: 'Daniel',
last_name: 'Olabemiwo',
email: 'dee@gmail.com',
phone: '+23832101',
message: 'Welcome to this side',
__v: 0
}
您可以通过将请求发送到使用缓存的Nestjs App中的请求来确认您选择的GUI(我喜欢TablePlus),并且您将看到数据已持续:
恭喜,您刚刚在Nestjs应用程序中添加了Redis Cache。
在本教程中,我们已成功地向我们的Nestjs应用程序添加了Redis Cache。
REDIS启用较低的应用程序延迟和非常高的数据访问。这使软件工程师可以构建高性能,可靠的解决方案。
就是这样!你怎么认为?在下面的评论中让我知道。