Caching is an important technique to improve the application performance. A cache acts as a temporary data store to provide high performance data access. In this post, we will learn how to setup NestJS Caching using Cache Manager and In-Memory Cache.

So let’s start.

1 – Installation

First step is to install the required packages. Mainly we need the cache-manager package. For development environment, we need the @types/cache-manager package.

We can install them using the below commands:

$ npm install cache-manager
$ npm install -D @types/cache-manager

2 – Enabling NestJS Caching

Technically, NestJS provides a unified API for different caching stores. However, for our example, we will use the in-memory data-store.

To enable caching, we need to import the CacheModule and call the register() method. See below code.

import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

3 – Using the In-Memory Cache Store

To interact with the CacheManager instance, we need to inject it into the service class. For our demo purpose, we will create a dummy applications that receives key/value pair as input and store it in the cache.

import {CACHE_MANAGER, Inject, Injectable } from '@nestjs/common';
import {Cache} from 'cache-manager';

@Injectable()
export class AppService {

  constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}

  async addToCache(key: string, item: string) {
    await this.cacheManager.set(key, item);
  }

  async getFromCache(key: string) {
    const value = await this.cacheManager.get(key);
    return value;
  }
}

In the above code snippet, the Cache class is imported from cache-manger. Also, the CACHE_MANAGER token comes from @nestjs/common package.

Also, we implement two methods. The addToCache() method accepts a key and item. Basically, the same is inserted into the cache store using the cache-manager instance.

Next, we implement getFromCache(). Basically, this method accepts a key as input and gets the value from the cache store.

We also implement a controller to call these methods. See below.

import { Body, Controller, Get, HttpStatus, Param, Post, Res } from '@nestjs/common';
import { AppService } from './app.service';
import { CacheEntry } from './cache-entry.model';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Post('/cache')
  async addToCache(@Body() cacheEntry: CacheEntry) {
    await this.appService.addToCache(cacheEntry.key, cacheEntry.item);
  }

  @Get('/cache/:key')
  async getFromCache(@Res() response, @Param('key') key) {
    const value = await this.appService.getFromCache(key);
    console.log(value)
    return response.status(HttpStatus.OK).json(value);
  }
}

You can read more about controllers and services in our detailed posts on NestJS Controllers and NestJS Providers.

4 – TTL Configuration

The default expiration time of the cache is 5 seconds. However, we can manually specify the TTL (Time To Live) time as well for a specific key as well.

Basically, we have to specify the TTL while using the set() method.

await this.appService.addToCache(cacheEntry.key, cacheEntry.item, { ttl: 1000 });

This will set TTL to 1000 milliseconds.

Also, we can disable expiration of the cache item by setting ttl property to 0:

await this.appService.addToCache(cacheEntry.key, cacheEntry.item, { ttl: 0 });

5 – Removing an Item from Cache

To remove an item from cache, we need to use the del() method.

await this.cacheManager.del(cacheEntry.key);

Also, we can clear the entire cache by using the reset() method.

await this.cacheManager.reset();

6 – Customize NestJS Caching Options

We can also customize the caching options while registering the CacheModule. See below:

import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [CacheModule.register({
    ttl: 1, // seconds
    max: 5, // maximum number of items in cache
  })
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

The max property defines how many items can reside in a cache at any given point in time.

7 – Enabling Global Cache Module

If we wish to use caching in other modules, we have to import CacheModule. However, we can also declare it as a global module as below:

import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [CacheModule.register({
    isGlobal: true
  })
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Conclusion

With this, we have successfully learnt how to setup NestJS Caching with Cache Manager and In-Memory Cache Store. We also explore the various configuration options.


Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *