diff --git a/.env.dist b/.env.dist index 32d1b7a..80a314c 100644 --- a/.env.dist +++ b/.env.dist @@ -13,6 +13,9 @@ RMQ_URI=amqp://v3-broker:5672 POSTGRES_IMAGE=postgres:15.0 # REDIS -REDIS_IMAGE=redis/redis-stack:latest +REDIS_IMAGE=redis:7.0-alpine REDIS_HOST=v3-user-redis REDIS_PORT=6379 + +# CACHE +CACHE_TTL=5000 diff --git a/.env.test b/.env.test index 4169556..a41a451 100644 --- a/.env.test +++ b/.env.test @@ -6,13 +6,5 @@ SERVICE_CONFIGURATION_DOMAIN=USER # PRISMA DATABASE_URL="postgresql://user:user@localhost:5601/user?schema=public" -# RABBIT MQ -RMQ_URI=amqp://v3-broker:5672 - # POSTGRES POSTGRES_IMAGE=postgres:15.0 - -# REDIS -REDIS_IMAGE=redis/redis-stack:latest -REDIS_HOST=v3-user-redis -REDIS_PORT=6379 diff --git a/docker-compose.yml b/docker-compose.yml index 9ade76b..a89364d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,8 +25,7 @@ services: container_name: v3-user-redis image: ${REDIS_IMAGE} ports: - - 6379:6379 - - 8101:8001 + - 6501:6379 env_file: - .env networks: diff --git a/package-lock.json b/package-lock.json index 7fdf49c..c076b71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,8 @@ "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", + "cache-manager": "^5.1.4", + "cache-manager-ioredis-yet": "^1.1.0", "class-transformer": "^0.5.1", "dotenv-cli": "^6.0.0", "ioredis": "^5.3.0" @@ -3530,6 +3532,35 @@ "node": ">= 0.8" } }, + "node_modules/cache-manager": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-5.1.4.tgz", + "integrity": "sha512-beXzzuboV6I0AkU25udrd8tRxFbU6c5m7+3eOdmznSVNkyKe0+uTK8EtcuhTwqc/wAYrAGl62w3s58rjKnrO6g==", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "^7.14.0" + } + }, + "node_modules/cache-manager-ioredis-yet": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cache-manager-ioredis-yet/-/cache-manager-ioredis-yet-1.1.0.tgz", + "integrity": "sha512-bGBAq8oNzzNkO2dwlYGWBxNXrz4w8FUTpe3nfUydJ6bm1ixKEcSUKYksGokQMaRgqkQjMbIHWFkvb8p+V9ZKqw==", + "dependencies": { + "cache-manager": "^5.1.0", + "ioredis": "^5.2.3" + }, + "engines": { + "node": ">= 16.17.0" + } + }, + "node_modules/cache-manager/node_modules/lru-cache": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", + "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", + "engines": { + "node": ">=12" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -6489,6 +6520,11 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -11702,6 +11738,31 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, + "cache-manager": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-5.1.4.tgz", + "integrity": "sha512-beXzzuboV6I0AkU25udrd8tRxFbU6c5m7+3eOdmznSVNkyKe0+uTK8EtcuhTwqc/wAYrAGl62w3s58rjKnrO6g==", + "requires": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "^7.14.0" + }, + "dependencies": { + "lru-cache": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", + "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==" + } + } + }, + "cache-manager-ioredis-yet": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cache-manager-ioredis-yet/-/cache-manager-ioredis-yet-1.1.0.tgz", + "integrity": "sha512-bGBAq8oNzzNkO2dwlYGWBxNXrz4w8FUTpe3nfUydJ6bm1ixKEcSUKYksGokQMaRgqkQjMbIHWFkvb8p+V9ZKqw==", + "requires": { + "cache-manager": "^5.1.0", + "ioredis": "^5.2.3" + } + }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -13905,6 +13966,11 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", diff --git a/package.json b/package.json index 5712de9..5d94276 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,8 @@ "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", + "cache-manager": "^5.1.4", + "cache-manager-ioredis-yet": "^1.1.0", "class-transformer": "^0.5.1", "dotenv-cli": "^6.0.0", "ioredis": "^5.3.0" diff --git a/src/modules/users/adapters/primaries/users.controller.ts b/src/modules/users/adapters/primaries/users.controller.ts index 82b18a3..b48d00f 100644 --- a/src/modules/users/adapters/primaries/users.controller.ts +++ b/src/modules/users/adapters/primaries/users.controller.ts @@ -1,6 +1,12 @@ import { Mapper } from '@automapper/core'; import { InjectMapper } from '@automapper/nestjs'; -import { Controller, UsePipes } from '@nestjs/common'; +import { + CacheInterceptor, + CacheKey, + Controller, + UseInterceptors, + UsePipes, +} from '@nestjs/common'; import { CommandBus, QueryBus } from '@nestjs/cqrs'; import { GrpcMethod, RpcException } from '@nestjs/microservices'; import { DatabaseException } from '../../../database/src/exceptions/database.exception'; @@ -33,6 +39,8 @@ export class UsersController { ) {} @GrpcMethod('UsersService', 'FindAll') + @UseInterceptors(CacheInterceptor) + @CacheKey('UsersServiceFindAll') async findAll(data: FindAllUsersRequest): Promise> { const userCollection = await this._queryBus.execute( new FindAllUsersQuery(data), @@ -46,6 +54,8 @@ export class UsersController { } @GrpcMethod('UsersService', 'FindOneByUuid') + @UseInterceptors(CacheInterceptor) + @CacheKey('UsersServiceFindOneByUuid') async findOneByUuid(data: FindUserByUuidRequest): Promise { try { const user = await this._queryBus.execute(new FindUserByUuidQuery(data)); diff --git a/src/modules/users/users.module.ts b/src/modules/users/users.module.ts index ac44fea..33b34a7 100644 --- a/src/modules/users/users.module.ts +++ b/src/modules/users/users.module.ts @@ -1,7 +1,9 @@ import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq'; -import { Module } from '@nestjs/common'; +import { RedisClientOptions } from '@liaoliaots/nestjs-redis'; +import { CacheModule, Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { CqrsModule } from '@nestjs/cqrs'; +import { redisStore } from 'cache-manager-ioredis-yet'; import { DatabaseModule } from '../database/database.module'; import { UsersController } from './adapters/primaries/users.controller'; import { LoggingMessager } from './adapters/secondaries/logging.messager'; @@ -36,6 +38,17 @@ import { UserProfile } from './mappers/user.profile'; }), inject: [ConfigService], }), + CacheModule.registerAsync({ + imports: [ConfigModule], + useFactory: async (configService: ConfigService) => ({ + store: await redisStore({ + host: configService.get('REDIS_HOST'), + port: configService.get('REDIS_PORT'), + ttl: configService.get('CACHE_TTL'), + }), + }), + inject: [ConfigService], + }), ], controllers: [UsersController], providers: [