23: cache
This commit is contained in:
86
package-lock.json
generated
86
package-lock.json
generated
@@ -12,6 +12,7 @@
|
||||
"@elastic/elasticsearch": "^9.0.2",
|
||||
"@hapi/joi": "^17.1.1",
|
||||
"@neondatabase/serverless": "^1.0.0",
|
||||
"@nestjs/cache-manager": "^3.0.1",
|
||||
"@nestjs/common": "^11.0.1",
|
||||
"@nestjs/config": "^4.0.2",
|
||||
"@nestjs/core": "^11.0.1",
|
||||
@@ -29,6 +30,7 @@
|
||||
"@types/uuid": "^10.0.0",
|
||||
"aws-sdk": "^2.1692.0",
|
||||
"bcrypt": "^5.1.1",
|
||||
"cache-manager": "^6.4.3",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.2",
|
||||
"cookie-parser": "^1.4.7",
|
||||
@@ -2008,6 +2010,39 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@keyv/serialize": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.3.tgz",
|
||||
"integrity": "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@keyv/serialize/node_modules/buffer": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@lukeed/csprng": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz",
|
||||
@@ -2407,6 +2442,19 @@
|
||||
"node": ">=19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@nestjs/cache-manager": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/cache-manager/-/cache-manager-3.0.1.tgz",
|
||||
"integrity": "sha512-4UxTnR0fsmKL5YDalU2eLFVnL+OBebWUpX+hEduKGncrVKH4PPNoiRn1kXyOCjmzb0UvWgqubpssNouc8e0MCw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^9.0.0 || ^10.0.0 || ^11.0.0",
|
||||
"@nestjs/core": "^9.0.0 || ^10.0.0 || ^11.0.0",
|
||||
"cache-manager": ">=6",
|
||||
"keyv": ">=5",
|
||||
"rxjs": "^7.8.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@nestjs/cli": {
|
||||
"version": "11.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-11.0.7.tgz",
|
||||
@@ -5818,6 +5866,15 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/cache-manager": {
|
||||
"version": "6.4.3",
|
||||
"resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-6.4.3.tgz",
|
||||
"integrity": "sha512-VV5eq/QQ5rIVix7/aICO4JyvSeEv9eIQuKL5iFwgM2BrcYoE0A/D1mNsAHJAsB0WEbNdBlKkn6Tjz6fKzh/cKQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"keyv": "^5.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/cacheable-lookup": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz",
|
||||
@@ -5847,6 +5904,16 @@
|
||||
"node": ">=14.16"
|
||||
}
|
||||
},
|
||||
"node_modules/cacheable-request/node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
||||
@@ -7664,6 +7731,16 @@
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/flat-cache/node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/flatbuffers": {
|
||||
"version": "24.12.23",
|
||||
"resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-24.12.23.tgz",
|
||||
@@ -9613,13 +9690,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||
"dev": true,
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.3.tgz",
|
||||
"integrity": "sha512-Rwu4+nXI9fqcxiEHtbkvoes2X+QfkTRo1TMkPfwzipGsJlJO/z69vqB4FNl9xJ3xCpAcbkvmEabZfPzrwN3+gQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"json-buffer": "3.0.1"
|
||||
"@keyv/serialize": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/kind-of": {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"@elastic/elasticsearch": "^9.0.2",
|
||||
"@hapi/joi": "^17.1.1",
|
||||
"@neondatabase/serverless": "^1.0.0",
|
||||
"@nestjs/cache-manager": "^3.0.1",
|
||||
"@nestjs/common": "^11.0.1",
|
||||
"@nestjs/config": "^4.0.2",
|
||||
"@nestjs/core": "^11.0.1",
|
||||
@@ -40,6 +41,7 @@
|
||||
"@types/uuid": "^10.0.0",
|
||||
"aws-sdk": "^2.1692.0",
|
||||
"bcrypt": "^5.1.1",
|
||||
"cache-manager": "^6.4.3",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.2",
|
||||
"cookie-parser": "^1.4.7",
|
||||
|
||||
19
src/posts/httpCache.interceptor.ts
Normal file
19
src/posts/httpCache.interceptor.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { CACHE_KEY_METADATA, CacheInterceptor, } from '@nestjs/cache-manager';
|
||||
import {ExecutionContext, Injectable} from "@nestjs/common";
|
||||
|
||||
@Injectable()
|
||||
export class HttpCacheInterceptor extends CacheInterceptor {
|
||||
trackBy(context: ExecutionContext): string | undefined {
|
||||
const cacheKey = this.reflector.get(
|
||||
CACHE_KEY_METADATA,
|
||||
context.getHandler(),
|
||||
);
|
||||
|
||||
if (cacheKey) {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
return `${cacheKey}-${request._parsedUrl.query}`;
|
||||
}
|
||||
|
||||
return super.trackBy(context);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,8 @@ import {UpdatePostDto} from './dto/update-post.dto';
|
||||
import JwtAuthenticationGuard from "../authentication/jwt-authentication.guard";
|
||||
import RequestWithUser from "../authentication/requestWithUser.interface";
|
||||
import {PaginationParams} from "../utils/types/paginationParams";
|
||||
import { CacheInterceptor, CacheKey, CacheTTL } from '@nestjs/cache-manager';
|
||||
import {GET_POSTS_CACHE_KEY} from "./postsCacheKey.constant";
|
||||
|
||||
@Controller('posts')
|
||||
@UseInterceptors(ClassSerializerInterceptor)
|
||||
@@ -30,7 +32,9 @@ export class PostsController {
|
||||
return this.postsService.createPost(post, req.user);
|
||||
}
|
||||
|
||||
|
||||
@UseInterceptors(CacheInterceptor)
|
||||
@CacheKey(GET_POSTS_CACHE_KEY)
|
||||
@CacheTTL(120)
|
||||
@Get()
|
||||
async getPosts(
|
||||
@Query('search') search: string,
|
||||
|
||||
@@ -6,10 +6,20 @@ import User from "../users/entities/user.entity";
|
||||
import Post from "./entities/post.entity";
|
||||
import PostsSearchService from "./postsSearch.service";
|
||||
import {SearchModule} from "../search/search.module";
|
||||
import { CacheModule } from '@nestjs/cache-manager';
|
||||
|
||||
@Module({
|
||||
controllers: [PostsController],
|
||||
imports: [TypeOrmModule.forFeature([Post]), SearchModule],
|
||||
imports: [
|
||||
CacheModule.register(
|
||||
{
|
||||
ttl: 5,
|
||||
max: 100
|
||||
}
|
||||
),
|
||||
TypeOrmModule.forFeature([Post]),
|
||||
SearchModule
|
||||
],
|
||||
providers: [PostsService, PostsSearchService],
|
||||
exports: [PostsService, PostsSearchService],
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Injectable} from '@nestjs/common';
|
||||
import {Inject, Injectable} from '@nestjs/common';
|
||||
import {CreatePostDto} from './dto/create-post.dto';
|
||||
import {UpdatePostDto} from './dto/update-post.dto';
|
||||
import User from "../users/entities/user.entity";
|
||||
@@ -8,22 +8,39 @@ import Post from './entities/post.entity';
|
||||
import {PostNotFoundException} from "./exception/postNotFound.exception";
|
||||
import PostsSearchService from "./postsSearch.service";
|
||||
import {In} from "typeorm";
|
||||
import { Cache } from 'cache-manager';
|
||||
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
||||
import {GET_POSTS_CACHE_KEY} from "./postsCacheKey.constant";
|
||||
|
||||
@Injectable()
|
||||
export class PostsService {
|
||||
|
||||
constructor(
|
||||
@InjectRepository(Post) private repo: Repository<Post>,
|
||||
private postsSearchService: PostsSearchService
|
||||
private postsSearchService: PostsSearchService,
|
||||
@Inject(CACHE_MANAGER) private cacheManager: Cache
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
async clearCache() {
|
||||
// const keys: string[] = this.cacheManager.stores.keys();
|
||||
//
|
||||
// await Promise.all(
|
||||
// keys
|
||||
// .filter((key) => key.startsWith(GET_POSTS_CACHE_KEY))
|
||||
// .map((key) => this.cacheManager.del(key)) // note: 'del', not 'delete'
|
||||
// );
|
||||
}
|
||||
|
||||
async createPost(post: CreatePostDto, user: User) {
|
||||
const newPost = this.repo.create({
|
||||
...post,
|
||||
author: user
|
||||
});
|
||||
await this.repo.save(newPost);
|
||||
await this.postsSearchService.indexPost(newPost);
|
||||
await this.clearCache();
|
||||
return newPost;
|
||||
}
|
||||
|
||||
@@ -91,6 +108,8 @@ export class PostsService {
|
||||
|
||||
});
|
||||
if (updatedPost) {
|
||||
await this.postsSearchService.update(updatedPost);
|
||||
await this.clearCache();
|
||||
return updatedPost
|
||||
}
|
||||
throw new PostNotFoundException(id);
|
||||
@@ -114,6 +133,7 @@ export class PostsService {
|
||||
});
|
||||
if (updatedPost) {
|
||||
await this.postsSearchService.update(updatedPost);
|
||||
await this.clearCache();
|
||||
return updatedPost;
|
||||
}
|
||||
throw new PostNotFoundException(id);
|
||||
@@ -125,5 +145,6 @@ export class PostsService {
|
||||
throw new PostNotFoundException(id);
|
||||
}
|
||||
await this.postsSearchService.remove(id);
|
||||
await this.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
1
src/posts/postsCacheKey.constant.ts
Normal file
1
src/posts/postsCacheKey.constant.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const GET_POSTS_CACHE_KEY = 'GET_POSTS_CACHE';
|
||||
Reference in New Issue
Block a user