From 78ce686f972f91622cfd09d7fa146c75b5e0d4cb Mon Sep 17 00:00:00 2001 From: x2Skyz Date: Thu, 13 Nov 2025 13:30:02 +0700 Subject: [PATCH] =?UTF-8?q?feat:=20=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B9=88?= =?UTF-8?q?=E0=B8=A1=E0=B8=A3=E0=B8=B0=E0=B8=9A=E0=B8=9A=20caching?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - เพิ่ม caching interceptor และ service - เพิ่ม configสำหรับ caching --- .../src/app/config/caching.config.ts | 11 ++++ .../src/app/services/caching.interceptor.ts | 52 +++++++++++++++++++ .../src/app/services/caching.service.ts | 41 +++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 accounting-ng-nuttakit/src/app/config/caching.config.ts create mode 100644 accounting-ng-nuttakit/src/app/services/caching.interceptor.ts create mode 100644 accounting-ng-nuttakit/src/app/services/caching.service.ts diff --git a/accounting-ng-nuttakit/src/app/config/caching.config.ts b/accounting-ng-nuttakit/src/app/config/caching.config.ts new file mode 100644 index 0000000..50cd10f --- /dev/null +++ b/accounting-ng-nuttakit/src/app/config/caching.config.ts @@ -0,0 +1,11 @@ +export const CACHEABLE_URLS = { + GET: [ + // Add GET URIs here that you want to cache + // e.g., '/api/data' + ], + POST: [ + '/api/web/accountingSearch' + // Add POST URIs here that you want to cache + // e.g., '/api/search' + ] +}; diff --git a/accounting-ng-nuttakit/src/app/services/caching.interceptor.ts b/accounting-ng-nuttakit/src/app/services/caching.interceptor.ts new file mode 100644 index 0000000..eb99616 --- /dev/null +++ b/accounting-ng-nuttakit/src/app/services/caching.interceptor.ts @@ -0,0 +1,52 @@ +import { Injectable } from '@angular/core'; +import { + HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse +} from '@angular/common/http'; +import { Observable, of } from 'rxjs'; +import { tap } from 'rxjs/operators'; +import { CachingService } from './caching.service'; +import { CACHEABLE_URLS } from '../config/caching.config'; + +@Injectable() +export class CachingInterceptor implements HttpInterceptor { + + constructor(private cache: CachingService) {} + + intercept(req: HttpRequest, next: HttpHandler): Observable> { + if (!this.isCacheable(req)) { + return next.handle(req); + } + + const cachedResponse = this.cache.get(this.getCacheKey(req)); + if (cachedResponse) { + return of(cachedResponse.clone()); + } + + return next.handle(req).pipe( + tap(event => { + if (event instanceof HttpResponse) { + this.cache.put(this.getCacheKey(req), event.clone()); + } + }) + ); + } + + private isCacheable(req: HttpRequest): boolean { + if (req.method === 'GET') { + return CACHEABLE_URLS.GET.some(url => req.urlWithParams.includes(url)); + } + + if (req.method === 'POST') { + return CACHEABLE_URLS.POST.some(url => req.urlWithParams.includes(url)); + } + + return false; + } + + private getCacheKey(req: HttpRequest): string { + if (req.method === 'POST') { + return req.urlWithParams + JSON.stringify(req.body); + } + return req.urlWithParams; + } +} diff --git a/accounting-ng-nuttakit/src/app/services/caching.service.ts b/accounting-ng-nuttakit/src/app/services/caching.service.ts new file mode 100644 index 0000000..7bfc58e --- /dev/null +++ b/accounting-ng-nuttakit/src/app/services/caching.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@angular/core'; +import { HttpResponse } from '@angular/common/http'; + +@Injectable({ + providedIn: 'root' +}) +export class CachingService { + private cache = new Map]>(); + private cacheDurationInMs = 600000; // 5 minutes + + constructor() { } + + get(key: string): HttpResponse | null { + const tuple = this.cache.get(key); + if (!tuple) { + return null; + } + + const expires = tuple[0]; + const httpResponse = tuple[1]; + + // Don't observe expired keys + const now = new Date(); + if (expires && expires.getTime() < now.getTime()) { + this.cache.delete(key); + return null; + } + + return httpResponse; + } + + put(key: string, value: HttpResponse): void { + const expires = new Date(); + expires.setMilliseconds(expires.getMilliseconds() + this.cacheDurationInMs); + this.cache.set(key, [expires, value]); + } + + clear(): void { + this.cache.clear(); + } +}