READ-THROUGH
Introduction
- This article will guide you on implementing
READ-THROUGHinNestJSwithRedisandPostgres - I will also use
@nestjs/cache-managerto create anAbstraction layer - That is a
Cache Interceptoracting as the single source of truth where the app only needs to retrieve data from it. If the cache is unavailable, it will query theDatabaseto fetch data and save it into the cache - Regarding the theoretical content, you can review the previous article where I covered it
Detail
Please install the following packages
bun add cache-manager cache-manager-redis-yet @nestjs/cache-manager
Create file module/cache-manager.module.ts to create CacheManagerModule connecting to Redis. The app will view this as the data source and only fetch data from here
import {CacheModule} from '@nestjs/cache-manager'
import {Module} from '@nestjs/common'
import {ConfigModule, ConfigService} from '@nestjs/config'
import {redisStore} from 'cache-manager-redis-yet'
@Module({
imports: [
CacheModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
store: await redisStore({
socket: {
host: configService.get<string>('REDIS_HOST'),
port: configService.get<number>('REDIS_PORT'),
},
ttl: 60000,
}),
}),
}),
],
exports: [CacheModule],
})
export class CacheManagerModule {}
Create file service/product.service.ts
import {CACHE_MANAGER} from '@nestjs/cache-manager'
import {Inject, Injectable} from '@nestjs/common'
import type {Cache} from 'cache-manager'
import {eq} from 'drizzle-orm'
import type {NodePgDatabase} from 'drizzle-orm/node-postgres'
import * as schema from 'src/drizzle-orm/schema/schema'
@Injectable()
export class ProductService {
constructor(
@Inject('DRIZZLE_DB') private readonly db: NodePgDatabase<typeof schema>,
@Inject(CACHE_MANAGER) private readonly cacheManager: Cache
) {}
async getProductById(id: number) {
const cacheKey = `product:${id}`
return await this.cacheManager.wrap(
cacheKey,
() =>
this.db
.select()
.from(schema.products)
.where(eq(schema.products.id, id))
.then(res => res[0]),
60000
)
}
}
- The function
getProductByIdis implemented followingREAD-THROUGH. When fetching data with cacheKey, if it is still in the cache, it will return immediately. If it has expired, it will query from the Database - The
60000part isTime To Live (TTL), which is an optional value allowing you to customize it for each individual case
Create file controller/product.controller.ts
import {Controller, Get, Param, ParseIntPipe} from '@nestjs/common'
import {ProductService} from 'src/service/product.service'
@Controller('products')
export class ProductsController {
constructor(private readonly productService: ProductService) {}
@Get(':id')
async getProduct(@Param('id', ParseIntPipe) id: number) {
return await this.productService.getProductById(id)
}
}
Modify file app.module.ts
import {Module} from '@nestjs/common'
import {ConfigModule} from '@nestjs/config'
import {ProductsController} from './controller/product.controller'
import {drizzleProvider} from './drizzle-orm'
import {CacheManagerModule} from './module/cache-manager.module'
import {ValkeyModule} from './module/valkey.module'
import {ProductService} from './service/product.service'
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: '.env',
}),
ValkeyModule,
CacheManagerModule,
],
controllers: [
ProductsController,
],
providers: [
drizzleProvider,
ProductService,
],
})
export class AppModule {}
As a result, after caching, the response speed will be much faster
Happy coding!
See more articles here.{:target="_target"}
Comments
Post a Comment