Angular의 캐시 인터셉터

3727 단어
이전 블로그에서 Angular의 인터셉터가 무엇인지 설명하고 기본 인증 인터셉터의 예를 들었습니다.
여기서 우리는 여러 인터셉터를 추가하는 방법과 인터셉터를 잡는 방법을 배울 것입니다.

첫 번째 블로그에서 컨텍스트를 빠르게 읽으십시오.

이제 여러 인터셉터를 추가하기 위해 먼저 루트 모듈 파일에 추가합니다.

import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
...

@NgModule({
  ...
  imports: [
    ... ,
    HttpClientModule
  ],
  providers: [
    ... ,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: InterceptorOne,
      multi: true,
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: InterceptorTwo,
      multi: true,
    }
  ],
  ...
})


참고: InterceptorOne 및 InterceptorTwo는 단지 예일 뿐이며 대신 자체 인터셉터 클래스를 추가해야 합니다.

이제 캐싱 인터셉터를 구현합니다.

이 인터셉터는 헤더에 true에 대한 cacheRequest 매개 변수가 포함된 경우에만 요청을 캐시합니다.

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';

import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs';
import { tap } from 'rxjs/operators';
import { CacheService } from './cache.service';

@Injectable()
export class CachingInterceptor implements HttpInterceptor {

  constructor(private readonly cacheService: CacheService) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // Don't cache if it's not a GET request
    if (req.method !== 'GET') {
      return next.handle(req);
    }

    // delete cache if no header is set by service's method
    if (!req.headers.get('cacheRequest')) {
      if (this.cacheService.cacheMap.get(req.urlWithParams)) {
        this.cacheService.cacheMap.delete(req.urlWithParams);
      }

      return next.handle(req);
    }

    // Checked if there is cached data for this URI
    const cachedResponse = this.cacheService.getFromCache(req);
    if (cachedResponse) {
      // In case of parallel requests to same URI,
      // return the request already in progress
      // otherwise return the last cached data
      return (cachedResponse instanceof Observable) ? cachedResponse : of(cachedResponse.clone());
    }

    // If the request of going through for first time
    // then let the request proceed and cache the response
    return next.handle(req)
        .pipe(tap(event => {
            if (event instanceof HttpResponse) {
                this.cacheService.addToCache(req, event);
            }
        }));
  }
}


캐시 서비스 : 캐시 저장 및 검색

import { HttpRequest, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable()
export class CacheService  {
  cacheMap = new Map<any, any>(null);

  getFromCache(req: HttpRequest<any>): HttpResponse<any> | undefined {
    const url = req.urlWithParams;
    const cached = this.cacheMap.get(url);

    if (!cached) {
      return undefined;
    }

    return (this.cacheMap.get(url)).response;
  }

  addToCache(req: HttpRequest<any>, response: HttpResponse<any>): void {
    const url = req.urlWithParams;
    const entry = { url, response, addedTime: Date.now() };
    this.cacheMap.set(url, entry);
  }
}


샘플 요청 받기

getMethod(int param1, cache = false): any {
    let headers: HttpHeaders;
    if (cache) {
      headers = new HttpHeaders({ 'cacheRequest': 'true' });
    }

    return this.http.get(
      'http://apiUrl',
      { headers }
    );
  }

좋은 웹페이지 즐겨찾기