Implementasi Redis sebagai Cache Store
Pada contoh ini kita akan coba implementasi redis sebagai cache management dari NestJS. untuk studi kasus kita akan implementasikan pada service order.
Pertama kita tambahkan RedisService
pada OrderService
Implementasi Redis di OrderService
import {
HttpException,
HttpStatus,
Inject,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import BaseResponse from 'src/utils/response/base.response';
import { Between, Like, Repository } from 'typeorm';
import { Order } from './order.entity';
import { ResponsePagination, ResponseSuccess } from 'src/interface/response';
import { CreateOrderDto, UpdateOrderDto, findAllOrderDto } from './order.dto';
import { REQUEST } from '@nestjs/core';
import { Workbook } from 'exceljs';
import { Response } from 'express';
import { KafkaService } from 'src/kafka/kafka.service';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';
import { RedisService } from 'src/redis/redis.service';
@Injectable()
export class OrderService extends BaseResponse {
constructor(
@InjectRepository(Order)
private readonly orderRepository: Repository<Order>,
@Inject(REQUEST) private req: any,
private readonly kafkaService: KafkaService,
private readonly redisService: RedisService,
) {
super();
}
Kemudian kita ubah sedikit method findById
pada orderService
seperti berikut.
async findById(id: number): Promise<ResponseSuccess> {
const cachedData = await this.redisService.getCacheKey(`order_${id}`);
if (cachedData) {
return this._success('Getting data from cache!', cachedData);
}
const result = await this.orderRepository.findOne({
where: {
id: id,
},
relations: [
'created_by',
'konsumen',
'order_detail',
'order_detail.produk',
],
select: {
id: true,
nomor_order: true,
status: true,
total_bayar: true,
tanggal_order: true,
konsumen: {
id: true,
nama_konsumen: true,
},
created_by: {
id: true,
nama: true,
},
order_detail: {
id: true,
jumlah: true,
produk: {
id: true,
nama_produk: true,
harga: true,
},
},
},
});
await this.redisService.setCacheKey({ key: `order_${id}`, data: result });
return this._success('OK', result);
}
Pada kode di atas kita tambahkan perintah agar melakukan pengecekan , apakah data yang diminta berada dalam cache di redis. Jika sudah ada maka data tersebut akan dijadikan response ke client, namun jika tidak akan akan dikakukan query ke database. Setelah mendapatkan data dari database, data tersbut akan disimpan ke dalam redis agar dapat digunakan untuk request selanjutnya.
Testing dengan Postman
Testing saat findById pada Detail
Testing saat Update Detail
Pada saat testing update data, ternyata masih ada kelemahan dari kode kita. Ketika kita berhasil update detail id 1 tersebut, kemudian saat get detail kembali maka data yg diberikan masih data yang lama, padahal data sudah diupdate. Untuk menyelesaikan masalah ini, kita tambahkan kode untuk menghapus cache data tersebut di redis jika update berhasil.
async updateOrder(
id: number,
payload: UpdateOrderDto,
): Promise<ResponseSuccess> {
const check = await this.orderRepository.findOne({
where: {
id: id,
},
});
if (!check) {
throw new HttpException('Data tidak ditemukan', HttpStatus.NOT_FOUND);
}
payload.order_detail &&
payload.order_detail.forEach((item) => {
item.created_by = this.req.user.id;
});
const order = await this.orderRepository.save({ ...payload, id: id });
this.redisService.deleteCacheKey(`order_${id}`)
return this._success('OK', order);
}
Testing Kembali