Skip to content

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

order.service.ts
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.

order.service.ts
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

alt text alt text alt text

Testing saat Update Detail

alt text alt text

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.

order.service.ts
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

alt text alt text