Реализация кэширования на Angular с перехватчиком только для нескольких запросов и не для каждого запроса условно через логическое значение.
Я проверял онлайн-решения о кэшировании только нескольких запросов и не всех.К сожалению, нет подходящего решения для этой цели.Поэтому я решил написать одну очень простую методологию кэширования для кэширования определенных запросов.
Это можно сделать следующим образом:
Создайте cache.interceptor & cache.service, как показано ниже, и добавьте его впровайдеры app.module, например, так:
providers:[
CacheService,
{ provide: HTTP_INTERCEPTORS, useClass: CachingInterceptor, multi: true }]
Код CachingInterceptor: перехватчик будет кэшировать запросы только тогда, когда он увидит определенный заголовок ('cache-response'), установленный вашими службами, которые выполняют вызов http.
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
// Add the service we created in Step 1
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('cache-response')) {
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);
}
}));
}
}
Код CacheService: эта служба используется для добавления / получения из кэша.
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.url;
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({ 'cache-response': 'true' });
}
return this.http.get(
'http://apiUrl',
{ headers }
);
}
И это все.У вас есть перехватчик, который запрашивает только кеш с установленным заголовком.