想要将Nestjs与其他Redis命令一起使用



我尝试将nestjs后端和redis实现为缓存。我可以按照官方文件做https://docs.nestjs.com/techniques/caching#in-内存缓存。

我使用包cache-manager-redis-storeapp.module.ts中的代码如下所示。

import { Module, CacheModule } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import * as redisStore from 'cache-manager-redis-store';
import * as Joi from 'joi';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [
CacheModule.registerAsync({
imports: [
ConfigModule.forRoot({
validationSchema: Joi.object({
REDIS_HOST: Joi.string().default('localhost'),
REDIS_PORT: Joi.number().default(6379),
REDIS_PASSWORD: Joi.string(),
}),
}),
],
useFactory: async (configService: ConfigService) => ({
store: redisStore,
auth_pass: configService.get('REDIS_PASSWORD'),
host: configService.get('REDIS_HOST'),
port: configService.get('REDIS_PORT'),
ttl: 0,
}),
inject: [ConfigService],
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

有了这个设置,我可以按预期使用getset,但我想使用其他redis命令,如hgetzadd。不幸的是,我在任何地方都找不到导游。

我认为一定有办法,因为cache-manager-redis-store包说它只是将配置传递给底层的node_redis包。而node-redis包可以使用那些花哨的redis命令。

如果您有解决方案,我们将不胜感激。

感谢Micael Levi和Hamidreza Vakilian的帮助。我做了更多的研究,找到了我的解决方案,所以我会分享给其他有同样问题的人。

cache-manager-redis-store似乎只允许正常的redis操作,如果你想使用更多,你必须按照Micael的建议访问cacheManager.store.getClient()

Cache接口没有getClient,但RedisCache有!问题是cache-manager-redis-store包中的RedisCache接口没有为外部用户导出这些接口。

解决此问题的最简单方法是为自己创建redis.interface.ts或任何名称。

import { Cache, Store } from 'cache-manager';
import { RedisClient } from 'redis';
export interface RedisCache extends Cache {
store: RedisStore;
}
export interface RedisStore extends Store {
name: 'redis';
getClient: () => RedisClient;
isCacheableValue: (value: any) => boolean;
}

现在您可以将Cache替换为RedisCache接口。

用法如下。

import {
CACHE_MANAGER,
Inject,
Injectable,
} from '@nestjs/common';
import { RedisClient } from 'redis';
import { RedisCache } from './interface/redis.interface';
@Injectable()
export class RedisService {
private redisClient: RedisClient;
constructor(@Inject(CACHE_MANAGER) private cacheManager: RedisCache) {
this.redisClient = this.cacheManager.store.getClient();
}
hgetall() {
this.redisClient.hgetall('mykey', (err, reply) => {
console.log(reply);
})
}
}

请注意,这些redisClient命令不返回值,因此必须使用回调来获取值。

正如你所看到的,答案是回调结构,我更喜欢awaitasync,所以我做了更多的工作。

import {
BadRequestException,
CACHE_MANAGER,
Inject,
Injectable,
} from '@nestjs/common';
import { RedisClient } from 'redis';
import { RedisCache } from './interface/redis.interface';
@Injectable()
export class RedisService {
private redisClient: RedisClient;
constructor(@Inject(CACHE_MANAGER) private cacheManager: RedisCache) {
this.redisClient = this.cacheManager.store.getClient();
}
async hgetall(key: string): Promise<{ [key: string]: string }> {
return new Promise<{ [key: string]: string }>((resolve, reject) => {
this.redisClient.hgetall(key, (err, reply) => {
if (err) {
console.error(err);
throw new BadRequestException();
}
resolve(reply);
});
});
}
}

通过使用promise,我可以得到答案,就好像函数返回一样。用法如下。

import { Injectable } from '@nestjs/common';
import { RedisService } from './redis.service';
@Injectable()
export class UserService {
constructor(private readonly redisService: RedisService) {}
async getUserInfo(): Promise<{ [key: string]: string }> {
const userInfo = await this.redisService.hgetall('mykey');
return userInfo;
}
}

即使接口Cache(来自cache-manager)没有定义getClient方法,也可以通过调用
cacheManager.store.getClient()来检索底层redis客户端。我不知道什么是最好的打字方式。

返回的将是cache-manager-redis-store创建的Redis客户端

我建议使用nestjs-redis包。它与typescript兼容,并且依赖于ioredis包,因此您也可以获得所有其他Redis API。

我找到了另一种简单的方法!您可以从cache-manager-redis-yet导入RedisCache,这是一个官方包,由节点缓存管理器建议。

这是代码示例:

import { CACHE_MANAGER, Injectable, Inject } from '@nestjs/common';
import { RedisCache } from 'cache-manager-redis-yet';
@Injectable()
export class UserService {
constructor(@Inject(CACHE_MANAGER) private readonly cacheManager: RedisCache) {}
get redis() {
return this.cacheManager.store.client;
}
async getUserInfo(): Promise<{ [key: string]: string }> {
const userInfo = await this.redis.hGetAll('mykey');
return userInfo;
}
}

相关内容

  • 没有找到相关文章

最新更新