ng-http-caching 20.0.1 → 21.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,663 +1,663 @@
1
- # NgHttpCaching [![Build Status](https://travis-ci.org/nigrosimone/ng-http-caching.svg?branch=master)](https://travis-ci.com/github/nigrosimone/ng-http-caching) [![Coverage Status](https://coveralls.io/repos/github/nigrosimone/ng-http-caching/badge.svg?branch=master)](https://coveralls.io/github/nigrosimone/ng-http-caching?branch=master) [![NPM version](https://img.shields.io/npm/v/ng-http-caching.svg)](https://www.npmjs.com/package/ng-http-caching)
2
-
3
- Cache for HTTP requests in Angular application.
4
-
5
- ## Description
6
-
7
- Sometime there is a need to cache the HTTP requests so that browser doesn’t have to hit server to fetch same data when same service is invoked serially or in parallel. `NgHttpCaching` intercept all request are made, try to retrieve a cached instance of the response and then return the cached response or send the request to the backend. Once the operation has completed cache the response.
8
-
9
- See the [stackblitz demo](https://stackblitz.com/edit/demo-ng-http-caching?file=src%2Fapp%2Fapp.component.ts).
10
-
11
- ## Features
12
-
13
- ✅ HTTP caching<br>
14
- ✅ Handles simultaneous/parallel requests<br>
15
- ✅ Automatic garbage collector of cache<br>
16
- ✅ More than 90% unit tested<br>
17
- ✅ LocalStorage, SessionStorage, MemoryStorage and custom cache storage<br>
18
- ✅ Check response headers cache-control and expires<br>
19
-
20
- ## Get Started
21
-
22
- *Step 1*: install `ng-http-caching`
23
-
24
- ```bash
25
- npm i ng-http-caching
26
- ```
27
-
28
- *Step 2*: Provide `NgHttpCaching` into your `bootstrapApplication`, eg.:
29
-
30
- ```ts
31
- import { bootstrapApplication } from '@angular/platform-browser';
32
- import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
33
- import { AppComponent } from './app.component';
34
- import { provideNgHttpCaching } from 'ng-http-caching';
35
-
36
- bootstrapApplication(AppComponent, {
37
- providers: [
38
- provideNgHttpCaching(),
39
- provideHttpClient(withInterceptorsFromDi())
40
- ]
41
- });
42
- ```
43
-
44
- if you want configure `ng-http-caching`, you can pass a configuration, eg.:
45
-
46
- ```ts
47
- import { bootstrapApplication } from '@angular/platform-browser';
48
- import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
49
- import { AppComponent } from './app.component';
50
- import { provideNgHttpCaching, NgHttpCachingConfig } from 'ng-http-caching';
51
-
52
- // your config...
53
- const ngHttpCachingConfig: NgHttpCachingConfig = {
54
- lifetime: 1000 * 10 // cache expire after 10 seconds
55
- };
56
-
57
- bootstrapApplication(AppComponent, {
58
- providers: [
59
- provideNgHttpCaching(ngHttpCachingConfig),
60
- provideHttpClient(withInterceptorsFromDi())
61
- ]
62
- });
63
- ```
64
-
65
- ## Config
66
-
67
- This is all the configuration interface, see below for the detail of each config.
68
-
69
- ```ts
70
- // all configuration are optionally
71
- export interface NgHttpCachingConfig {
72
- version?: string;
73
- lifetime?: number;
74
- allowedMethod?: string[];
75
- cacheStrategy?: NgHttpCachingStrategy;
76
- store?: NgHttpCachingStorageInterface;
77
- isExpired?: (entry: NgHttpCachingEntry) => boolean | undefined | void;
78
- isValid?: (entry: NgHttpCachingEntry) => boolean | undefined | void;
79
- isCacheable?: (req: HttpRequest<any>) => boolean | undefined | void;
80
- getKey?: (req: HttpRequest<any>) => string | undefined | void;
81
- }
82
- ```
83
-
84
- ### version (string - default: VERSION.major)
85
- Cache version. When you have a breaking change, change the version, and it'll delete the current cache automatically.
86
- The default value is Angular major version (eg. 13), in this way, the cache is invalidated on every Angular upgrade.
87
-
88
- ### lifetime (number - default: 3.600.000)
89
- Number of millisecond that a response is stored in the cache.
90
- You can set specific "lifetime" for each request by add the header `X-NG-HTTP-CACHING-LIFETIME` (see example below).
91
-
92
- ### checkResponseHeaders (boolean - default false);
93
- If true response headers cache-control and expires are respected.
94
-
95
- ### allowedMethod (string[] - default: ['GET', 'HEAD'])
96
- Array of allowed HTTP methods to cache.
97
- You can allow multiple methods, eg.: `['GET', 'POST', 'PUT', 'DELETE', 'HEAD']` or
98
- allow all methods by: `['ALL']`. If `allowedMethod` is an empty array (`[]`), no response are cached.
99
- *Warning!* `NgHttpCaching` use the full url (url with query parameters) as unique key for the cached response,
100
- this is correct for the `GET` request but is _potentially_ wrong for other type of request (eg. `POST`, `PUT`).
101
- You can set a different "key" by customizing the `getKey` config method (see `getKey` section).
102
-
103
- ### cacheStrategy (enum NgHttpCachingStrategy - default: NgHttpCachingStrategy.ALLOW_ALL)
104
- Set the cache strategy, possible strategies are:
105
- - `NgHttpCachingStrategy.ALLOW_ALL`: All request are cacheable if HTTP method is into `allowedMethod`;
106
- - `NgHttpCachingStrategy.DISALLOW_ALL`: Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`;
107
-
108
- ### store (class of NgHttpCachingStorageInterface - default: NgHttpCachingMemoryStorage)
109
- Set the cache store. You can implement your custom store by implement the `NgHttpCachingStorageInterface` interface, eg.:
110
-
111
- ```ts
112
- import { NgHttpCachingConfig, NgHttpCachingStorageInterface } from 'ng-http-caching';
113
-
114
- class MyCustomStore implements NgHttpCachingStorageInterface {
115
- // ... your logic
116
- }
117
-
118
- const ngHttpCachingConfig: NgHttpCachingConfig = {
119
- store: new MyCustomStore(),
120
- };
121
- ```
122
-
123
- there is also a `withNgHttpCachingLocalStorage` a cache store with persistence into `localStorage`:
124
-
125
- ```ts
126
- import { NgHttpCachingConfig, withNgHttpCachingLocalStorage } from 'ng-http-caching';
127
-
128
- const ngHttpCachingConfig: NgHttpCachingConfig = {
129
- store: withNgHttpCachingLocalStorage(),
130
- };
131
- ```
132
-
133
- and a `withNgHttpCachingSessionStorage` a cache store with persistence into `sessionStorage`:
134
-
135
- ```ts
136
- import { NgHttpCachingConfig, withNgHttpCachingSessionStorage } from 'ng-http-caching';
137
-
138
- const ngHttpCachingConfig: NgHttpCachingConfig = {
139
- store: withNgHttpCachingSessionStorage(),
140
- };
141
- ```
142
-
143
- ### isExpired (function - default see NgHttpCachingService.isExpired());
144
- If this function return `true` the request is expired and a new request is send to backend, if return `false` isn't expired.
145
- If the result is `undefined`, the normal behaviour is provided.
146
- Example of customization:
147
-
148
- ```ts
149
- import { NgHttpCachingConfig, NgHttpCachingEntry } from 'ng-http-caching';
150
-
151
- const ngHttpCachingConfig: NgHttpCachingConfig = {
152
- isExpired: (entry: NgHttpCachingEntry): boolean | undefined => {
153
- // In this example a special API endpoint (/my-endpoint) send into the body response
154
- // an expireAt Date property. Only for this endpoint the expiration is provided by expireAt value.
155
- // For all the other endpoint normal behaviour is provided.
156
- if( entry.request.urlWithParams.indexOf('/my-endpoint') !== -1 ){
157
- return entry.response.body.expireAt.getTime() > Date.now();
158
- }
159
- // by returning "undefined" normal "ng-http-caching" workflow is applied
160
- return undefined;
161
- },
162
- };
163
- ```
164
-
165
- ### isValid (function - default see NgHttpCachingService.isValid());
166
- If this function return `true` the cache entry is valid and can be stored, if return `false` isn't valid.
167
- If the result is `undefined`, the normal behaviour is provided.
168
- Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.
169
- Example of customization:
170
-
171
- ```ts
172
- import { NgHttpCachingConfig, NgHttpCachingEntry } from 'ng-http-caching';
173
-
174
- const ngHttpCachingConfig: NgHttpCachingConfig = {
175
- isValid: (entry: NgHttpCachingEntry): boolean | undefined => {
176
- // In this example only response with status code 200 can be stored into the cache
177
- return entry.response.status === 200;
178
- },
179
- };
180
- ```
181
-
182
- ### isCacheable (function - default see NgHttpCachingService.isCacheable());
183
- If this function return `true` the request is cacheable, if return `false` isn't cacheable.
184
- If the result is `undefined`, the normal behaviour is provided.
185
- Example of customization:
186
-
187
- ```ts
188
- import { NgHttpCachingConfig } from 'ng-http-caching';
189
-
190
- const ngHttpCachingConfig: NgHttpCachingConfig = {
191
- isCacheable: (req: HttpRequest<any>): boolean | undefined => {
192
- // In this example the /my-endpoint isn't cacheable.
193
- // For all the other endpoint normal behaviour is provided.
194
- if( req.urlWithParams.indexOf('/my-endpoint') !== -1 ){
195
- return false;
196
- }
197
- // by returning "undefined" normal "ng-http-caching" workflow is applied
198
- return undefined;
199
- },
200
- };
201
- ```
202
-
203
-
204
- ### getKey (function - default see NgHttpCachingService.getKey());
205
- This function return the unique key (`string`) for store the response into the cache.
206
- If the result is `undefined`, the normal behaviour is provided.
207
- Example of customization:
208
-
209
- ```ts
210
- import { NgHttpCachingConfig } from 'ng-http-caching';
211
- import * as hash from 'object-hash'; // install object-hash with: npm i object-hash
212
-
213
- const hashOptions = {
214
- algorithm: 'md5',
215
- encoding: 'hex'
216
- };
217
-
218
- const ngHttpCachingConfig: NgHttpCachingConfig = {
219
- allowedMethod: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD'],
220
- getKey: (req: HttpRequest<any>): string | undefined => {
221
- // In this example the full request is hashed for provide an unique key for the cache.
222
- // This is important if you want support method like POST or PUT.
223
- return req.method + '@' + req.urlWithParams + '@' + hash(req.params, hashOptions) + '@' + hash(req.body, hashOptions);
224
- },
225
- };
226
- ```
227
-
228
- ## Headers
229
-
230
- `NgHttpCaching` use some custom headers for customize the caching behaviour.
231
- The supported headers are exported from the enum `NgHttpCachingHeaders`:
232
-
233
- ```ts
234
- export enum NgHttpCachingHeaders {
235
- ALLOW_CACHE = 'X-NG-HTTP-CACHING-ALLOW-CACHE',
236
- DISALLOW_CACHE = 'X-NG-HTTP-CACHING-DISALLOW-CACHE',
237
- LIFETIME = 'X-NG-HTTP-CACHING-LIFETIME',
238
- TAG = 'X-NG-HTTP-CACHING-TAG',
239
- }
240
- ```
241
-
242
- All those headers are removed before send the request to the backend.
243
-
244
- ### X-NG-HTTP-CACHING-ALLOW-CACHE (string: any value);
245
-
246
- If you have choose the `DISALLOW_ALL` cache strategy, you can mark specific request as cacheable by adding the header `X-NG-HTTP-CACHING-ALLOW-CACHE`, eg.:
247
-
248
- ```ts
249
- this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {
250
- headers: {
251
- [NgHttpCachingHeaders.ALLOW_CACHE]: '1',
252
- }
253
- }).subscribe(e => console.log);
254
- ```
255
-
256
- ### X-NG-HTTP-CACHING-DISALLOW-CACHE (string: any value);
257
-
258
- You can disallow specific request by add the header `X-NG-HTTP-CACHING-DISALLOW-CACHE`, eg.:
259
-
260
- ```ts
261
- this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {
262
- headers: {
263
- [NgHttpCachingHeaders.DISALLOW_CACHE]: '1',
264
- }
265
- }).subscribe(e => console.log);
266
- ```
267
-
268
- ### X-NG-HTTP-CACHING-LIFETIME (string: number of millisecond);
269
-
270
- You can set specific lifetime for request by add the header `X-NG-HTTP-CACHING-LIFETIME` with a string value as the number of millisecond, eg.:
271
-
272
- ```ts
273
- this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {
274
- headers: {
275
- [NgHttpCachingHeaders.LIFETIME]: (1000 * 60 * 60 * 24 * 365).toString(), // one year
276
- }
277
- }).subscribe(e => console.log);
278
- ```
279
-
280
- ### X-NG-HTTP-CACHING-TAG (string: tag name);
281
-
282
- You can tag multiple request by adding special header `X-NG-HTTP-CACHING-TAG` with the same tag and
283
- using `NgHttpCachingService.clearCacheByTag(tag: string)` for delete all the tagged request. Eg.:
284
-
285
- ```ts
286
- this.http.get('https://my-json-server.typicode.com/typicode/demo/db?id=1', {
287
- headers: {
288
- [NgHttpCachingHeaders.TAG]: 'foo',
289
- }
290
- }).subscribe(e => console.log);
291
- ```
292
-
293
- ## HttpContext
294
-
295
- You can override `NgHttpCachingConfig` methods:
296
- ```ts
297
- {
298
- isExpired?: (entry: NgHttpCachingEntry) => boolean | undefined | void;
299
- isValid?: (entry: NgHttpCachingEntry) => boolean | undefined | void;
300
- isCacheable?: (req: HttpRequest<any>) => boolean | undefined | void;
301
- getKey?: (req: HttpRequest<any>) => string | undefined | void;
302
- }
303
- ```
304
- with `HttpContextToken`, eg.:
305
- ```ts
306
- import { withNgHttpCachingContext } from 'ng-http-caching';
307
-
308
- const context = withNgHttpCachingContext({
309
- isExpired: (entry: NgHttpCachingEntry) => {
310
- console.log('context:isExpired', entry);
311
- },
312
- isCacheable: (req: HttpRequest<any>) => {
313
- console.log('context:isCacheable', req);
314
- },
315
- getKey: (req: HttpRequest<any>) => {
316
- console.log('context:getKey', req);
317
- },
318
- isValid: (entry: NgHttpCachingEntry) => {
319
- console.log('context:isValid', entry);
320
- }
321
- });
322
- this.http.get('https://my-json-server.typicode.com/typicode/demo/db?id=1', { context }).subscribe(e => console.log);
323
- ```
324
-
325
- ## Cache service
326
-
327
- You can inject into your component the `NgHttpCachingService` that expose some utils methods:
328
-
329
- ```ts
330
- export class NgHttpCachingService {
331
-
332
- /**
333
- * Return the config
334
- */
335
- getConfig(): Readonly<NgHttpCachingConfig>;
336
-
337
- /**
338
- * Return the queue map
339
- */
340
- getQueue(): Readonly<Map<string, Observable<HttpEvent<any>>>>;
341
-
342
- /**
343
- * Return the cache store
344
- */
345
- getStore(): Readonly<NgHttpCachingStorageInterface>;
346
-
347
- /**
348
- * Return response from cache
349
- */
350
- getFromCache<K, T>(req: HttpRequest<K>): Readonly<HttpResponse<T>> | undefined;
351
-
352
- /**
353
- * Add response to cache
354
- */
355
- addToCache<K, T>(req: HttpRequest<K>, res: HttpResponse<T>): boolean;
356
-
357
- /**
358
- * Delete response from cache
359
- */
360
- deleteFromCache<K>(req: HttpRequest<K>): boolean;
361
-
362
- /**
363
- * Clear the cache
364
- */
365
- clearCache(): void;
366
-
367
- /**
368
- * Clear the cache by key
369
- */
370
- clearCacheByKey(key: string): boolean;
371
-
372
- /**
373
- * Clear the cache by keys
374
- */
375
- clearCacheByKeys(keys: Array<string>): number;
376
-
377
- /**
378
- * Clear the cache by regex
379
- */
380
- clearCacheByRegex<K, T>(regex: RegExp): number;
381
-
382
- /**
383
- * Clear the cache by TAG
384
- */
385
- clearCacheByTag<K, T>(tag: string): number;
386
-
387
- /**
388
- * Run garbage collector (delete expired cache entry)
389
- */
390
- runGc<K, T>(): boolean;
391
-
392
- /**
393
- * Return true if cache entry is expired
394
- */
395
- isExpired<K, T>(entry: NgHttpCachingEntry<K, T>): boolean;
396
-
397
- /**
398
- * Return true if cache entry is valid for store in the cache
399
- * Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.
400
- */
401
- isValid<K, T>(entry: NgHttpCachingEntry<K, T>): boolean;
402
-
403
- /**
404
- * Return true if the request is cacheable
405
- */
406
- isCacheable<K>(req: HttpRequest<K>): boolean;
407
-
408
- /**
409
- * Return the cache key.
410
- * Default key is http method plus url with query parameters, eg.:
411
- * `GET@https://github.com/nigrosimone/ng-http-caching`
412
- */
413
- getKey<K>(req: HttpRequest<K>): string;
414
-
415
- /**
416
- * Return observable from cache
417
- */
418
- getFromQueue<K, T>(req: HttpRequest<K>): Observable<HttpEvent<T>> | undefined;
419
-
420
- /**
421
- * Add observable to cache
422
- */
423
- addToQueue<K, T>(req: HttpRequest<K>, obs: Observable<HttpEvent<T>>): void;
424
-
425
- /**
426
- * Delete observable from cache
427
- */
428
- deleteFromQueue<K>(req: HttpRequest<K>): boolean;
429
- }
430
- ```
431
-
432
- ## Examples
433
-
434
- Below there are some examples of use case.
435
-
436
- ### Example: exclude specific request from cache
437
-
438
- You can disallow specific request by add the header `X-NG-HTTP-CACHING-DISALLOW-CACHE`, eg.:
439
-
440
- ```ts
441
- import { Component, OnInit } from '@angular/core';
442
- import { HttpClient } from "@angular/common/http";
443
- import { NgHttpCachingHeaders } from 'ng-http-caching';
444
-
445
- @Component({
446
- selector: 'app-root',
447
- templateUrl: './app.component.html',
448
- styleUrls: ['./app.component.scss']
449
- })
450
- export class AppComponent implements OnInit {
451
-
452
- constructor(private http: HttpClient) {}
453
-
454
- ngOnInit(): void {
455
- // This request will never cache.
456
- // Note: all the "special" headers in NgHttpCachingHeaders are removed before send the request to the backend.
457
- this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {
458
- headers: {
459
- [NgHttpCachingHeaders.DISALLOW_CACHE]: '1',
460
- }
461
- }).subscribe(e => console.log);
462
- }
463
- }
464
- ```
465
-
466
- ### Example: set specific lifetime for request
467
-
468
- You can set specific lifetime for request by add the header `X-NG-HTTP-CACHING-LIFETIME` with a string value as the number of millisecond, eg.:
469
-
470
- ```ts
471
- import { Component, OnInit } from '@angular/core';
472
- import { HttpClient } from "@angular/common/http";
473
- import { NgHttpCachingHeaders } from 'ng-http-caching';
474
-
475
- @Component({
476
- selector: 'app-root',
477
- templateUrl: './app.component.html',
478
- styleUrls: ['./app.component.scss']
479
- })
480
- export class AppComponent implements OnInit {
481
-
482
- constructor(private http: HttpClient) {}
483
-
484
- ngOnInit(): void {
485
- // This request will expire from 365 days.
486
- // Note: all the "special" headers in NgHttpCachingHeaders are removed before send the request to the backend.
487
- this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {
488
- headers: {
489
- [NgHttpCachingHeaders.LIFETIME]: (1000 * 60 * 60 * 24 * 365).toString(),
490
- }
491
- }).subscribe(e => console.log);
492
- }
493
- }
494
- ```
495
-
496
- ### Example: mark specific request as cacheable (if cache strategy is DISALLOW_ALL)
497
-
498
- If you have choose the `DISALLOW_ALL` cache strategy, you can mark specific request as cacheable by adding the header `X-NG-HTTP-CACHING-ALLOW-CACHE`, eg.:
499
-
500
- ```ts
501
- import { Component, OnInit } from '@angular/core';
502
- import { HttpClient } from "@angular/common/http";
503
- import { NgHttpCachingHeaders } from 'ng-http-caching';
504
-
505
- @Component({
506
- selector: 'app-root',
507
- templateUrl: './app.component.html',
508
- styleUrls: ['./app.component.scss']
509
- })
510
- export class AppComponent implements OnInit {
511
-
512
- constructor(private http: HttpClient) {}
513
-
514
- ngOnInit(): void {
515
- // This request is marked as cacheable (this is necessary only if cache strategy is DISALLOW_ALL)
516
- // Note: all the "special" headers in NgHttpCachingHeaders are removed before send the request to the backend.
517
- this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {
518
- headers: {
519
- [NgHttpCachingHeaders.ALLOW_CACHE]: '1',
520
- }
521
- }).subscribe(e => console.log);
522
- }
523
- }
524
- ```
525
-
526
- ### Example: clear/flush all the cache
527
-
528
- If user switch the account (logout/login) or the application language, maybe ca be necessary clear all the cache, eg.:
529
-
530
- ```ts
531
- import { Component } from '@angular/core';
532
- import { NgHttpCachingService } from 'ng-http-caching';
533
-
534
- @Component({
535
- selector: 'app-root',
536
- templateUrl: './app.component.html',
537
- styleUrls: ['./app.component.scss']
538
- })
539
- export class AppComponent {
540
-
541
- constructor(private ngHttpCachingService: NgHttpCachingService) {}
542
-
543
- clearCache(): void {
544
- // Clear all the cache
545
- this.ngHttpCachingService.clearCache();
546
- }
547
- }
548
- ```
549
-
550
- ### Example: clear/flush specific cache entry
551
-
552
- If you want delete some cache entry, eg.:
553
-
554
- ```ts
555
- import { Component } from '@angular/core';
556
- import { NgHttpCachingService } from 'ng-http-caching';
557
-
558
- @Component({
559
- selector: 'app-root',
560
- templateUrl: './app.component.html',
561
- styleUrls: ['./app.component.scss']
562
- })
563
- export class AppComponent {
564
-
565
- constructor(private ngHttpCachingService: NgHttpCachingService) {}
566
-
567
- clearCache(key: string): boolean {
568
- // Clear the cache for the provided key
569
- return this.ngHttpCachingService.clearCacheByKey(key);
570
- }
571
- }
572
- ```
573
-
574
- ### Example: clear/flush specific cache entry by RegEx
575
-
576
- If you want delete some cache entry by RegEx, eg.:
577
-
578
- ```ts
579
- import { Component } from '@angular/core';
580
- import { NgHttpCachingService } from 'ng-http-caching';
581
-
582
- @Component({
583
- selector: 'app-root',
584
- templateUrl: './app.component.html',
585
- styleUrls: ['./app.component.scss']
586
- })
587
- export class AppComponent {
588
-
589
- constructor(private ngHttpCachingService: NgHttpCachingService) {}
590
-
591
- clearCacheByRegex(regEx: RegExp): void {
592
- // Clear the cache for the key that match regex
593
- this.ngHttpCachingService.clearCacheByRegex(regEx);
594
- }
595
- }
596
- ```
597
-
598
- ### Example: TAG request and clear/flush specific cache entry by TAG
599
-
600
- You can tag multiple request by adding special header `X-NG-HTTP-CACHING-TAG` with the same tag and
601
- using `NgHttpCachingService.clearCacheByTag(tag:
602
- )` for delete all the tagged request. Eg.:
603
-
604
- ```ts
605
- import { Component, OnInit } from '@angular/core';
606
- import { HttpClient } from "@angular/common/http";
607
- import { NgHttpCachingService } from 'ng-http-caching';
608
-
609
- @Component({
610
- selector: 'app-root',
611
- templateUrl: './app.component.html',
612
- styleUrls: ['./app.component.scss']
613
- })
614
- export class AppComponent {
615
-
616
- constructor(private ngHttpCachingService: NgHttpCachingService) {}
617
-
618
- ngOnInit(): void {
619
- // This request is tagged with "foo" keyword. You can tag multiple requests with the same tag and
620
- // using NgHttpCachingService.clearCacheByTag("foo") for delete all the tagged request.
621
- this.http.get('https://my-json-server.typicode.com/typicode/demo/db?id=1', {
622
- headers: {
623
- [NgHttpCachingHeaders.TAG]: 'foo',
624
- }
625
- }).subscribe(e => console.log);
626
-
627
- // This request is also tagged with "foo" keyword, and has another tag "baz".
628
- // You can add multiple tags comma separated.
629
- this.http.get('https://my-json-server.typicode.com/typicode/demo/db?id=2', {
630
- headers: {
631
- [NgHttpCachingHeaders.TAG]: 'foo,baz',
632
- }
633
- }).subscribe(e => console.log);
634
- }
635
-
636
- clearCacheForFoo(): void {
637
- // Clear the cache for all the entry have the tag 'foo'
638
- this.ngHttpCachingService.clearCacheByTag('foo');
639
- }
640
- }
641
- ```
642
-
643
- ## Alternatives
644
-
645
- Aren't you satisfied? there are some valid alternatives:
646
-
647
- - [@ngneat/cashew](https://www.npmjs.com/package/@ngneat/cashew)
648
- - [p3x-angular-http-cache-interceptor](https://www.npmjs.com/package/p3x-angular-http-cache-interceptor)
649
- - [@d4h/angular-http-cache](https://www.npmjs.com/package/@d4h/angular-http-cache)
650
-
651
-
652
- ## Support
653
-
654
- This is an open-source project. Star this [repository](https://github.com/nigrosimone/ng-http-caching), if you like it, or even [donate](https://www.paypal.com/paypalme/snwp). Thank you so much!
655
-
656
- ## My other libraries
657
-
658
- I have published some other Angular libraries, take a look:
659
-
660
- - [NgSimpleState: Simple state management in Angular with only Services and RxJS](https://www.npmjs.com/package/ng-simple-state)
661
- - [NgGenericPipe: Generic pipe for Angular application for use a component method into component template.](https://www.npmjs.com/package/ng-generic-pipe)
662
- - [NgLet: Structural directive for sharing data as local variable into html component template](https://www.npmjs.com/package/ng-let)
663
- - [NgForTrackByProperty: Angular global trackBy property directive with strict type checking](https://www.npmjs.com/package/ng-for-track-by-property)
1
+ # NgHttpCaching [![Build Status](https://travis-ci.org/nigrosimone/ng-http-caching.svg?branch=master)](https://travis-ci.com/github/nigrosimone/ng-http-caching) [![Coverage Status](https://coveralls.io/repos/github/nigrosimone/ng-http-caching/badge.svg?branch=master)](https://coveralls.io/github/nigrosimone/ng-http-caching?branch=master) [![NPM version](https://img.shields.io/npm/v/ng-http-caching.svg)](https://www.npmjs.com/package/ng-http-caching)
2
+
3
+ Cache for HTTP requests in Angular application.
4
+
5
+ ## Description
6
+
7
+ Sometime there is a need to cache the HTTP requests so that browser doesn’t have to hit server to fetch same data when same service is invoked serially or in parallel. `NgHttpCaching` intercept all request are made, try to retrieve a cached instance of the response and then return the cached response or send the request to the backend. Once the operation has completed cache the response.
8
+
9
+ See the [stackblitz demo](https://stackblitz.com/edit/demo-ng-http-caching-21?file=src%2Fmain.ts).
10
+
11
+ ## Features
12
+
13
+ ✅ HTTP caching<br>
14
+ ✅ Handles simultaneous/parallel requests<br>
15
+ ✅ Automatic garbage collector of cache<br>
16
+ ✅ More than 90% unit tested<br>
17
+ ✅ LocalStorage, SessionStorage, MemoryStorage and custom cache storage<br>
18
+ ✅ Check response headers cache-control and expires<br>
19
+
20
+ ## Get Started
21
+
22
+ *Step 1*: install `ng-http-caching`
23
+
24
+ ```bash
25
+ npm i ng-http-caching
26
+ ```
27
+
28
+ *Step 2*: Provide `NgHttpCaching` into your `bootstrapApplication`, eg.:
29
+
30
+ ```ts
31
+ import { bootstrapApplication } from '@angular/platform-browser';
32
+ import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
33
+ import { AppComponent } from './app.component';
34
+ import { provideNgHttpCaching } from 'ng-http-caching';
35
+
36
+ bootstrapApplication(AppComponent, {
37
+ providers: [
38
+ provideNgHttpCaching(),
39
+ provideHttpClient(withInterceptorsFromDi())
40
+ ]
41
+ });
42
+ ```
43
+
44
+ if you want configure `ng-http-caching`, you can pass a configuration, eg.:
45
+
46
+ ```ts
47
+ import { bootstrapApplication } from '@angular/platform-browser';
48
+ import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
49
+ import { AppComponent } from './app.component';
50
+ import { provideNgHttpCaching, NgHttpCachingConfig } from 'ng-http-caching';
51
+
52
+ // your config...
53
+ const ngHttpCachingConfig: NgHttpCachingConfig = {
54
+ lifetime: 1000 * 10 // cache expire after 10 seconds
55
+ };
56
+
57
+ bootstrapApplication(AppComponent, {
58
+ providers: [
59
+ provideNgHttpCaching(ngHttpCachingConfig),
60
+ provideHttpClient(withInterceptorsFromDi())
61
+ ]
62
+ });
63
+ ```
64
+
65
+ ## Config
66
+
67
+ This is all the configuration interface, see below for the detail of each config.
68
+
69
+ ```ts
70
+ // all configuration are optionally
71
+ export interface NgHttpCachingConfig {
72
+ version?: string;
73
+ lifetime?: number;
74
+ allowedMethod?: string[];
75
+ cacheStrategy?: NgHttpCachingStrategy;
76
+ store?: NgHttpCachingStorageInterface;
77
+ isExpired?: (entry: NgHttpCachingEntry) => boolean | undefined | void;
78
+ isValid?: (entry: NgHttpCachingEntry) => boolean | undefined | void;
79
+ isCacheable?: (req: HttpRequest<any>) => boolean | undefined | void;
80
+ getKey?: (req: HttpRequest<any>) => string | undefined | void;
81
+ }
82
+ ```
83
+
84
+ ### version (string - default: VERSION.major)
85
+ Cache version. When you have a breaking change, change the version, and it'll delete the current cache automatically.
86
+ The default value is Angular major version (eg. 13), in this way, the cache is invalidated on every Angular upgrade.
87
+
88
+ ### lifetime (number - default: 3.600.000)
89
+ Number of millisecond that a response is stored in the cache.
90
+ You can set specific "lifetime" for each request by add the header `X-NG-HTTP-CACHING-LIFETIME` (see example below).
91
+
92
+ ### checkResponseHeaders (boolean - default false);
93
+ If true response headers cache-control and expires are respected.
94
+
95
+ ### allowedMethod (string[] - default: ['GET', 'HEAD'])
96
+ Array of allowed HTTP methods to cache.
97
+ You can allow multiple methods, eg.: `['GET', 'POST', 'PUT', 'DELETE', 'HEAD']` or
98
+ allow all methods by: `['ALL']`. If `allowedMethod` is an empty array (`[]`), no response are cached.
99
+ *Warning!* `NgHttpCaching` use the full url (url with query parameters) as unique key for the cached response,
100
+ this is correct for the `GET` request but is _potentially_ wrong for other type of request (eg. `POST`, `PUT`).
101
+ You can set a different "key" by customizing the `getKey` config method (see `getKey` section).
102
+
103
+ ### cacheStrategy (enum NgHttpCachingStrategy - default: NgHttpCachingStrategy.ALLOW_ALL)
104
+ Set the cache strategy, possible strategies are:
105
+ - `NgHttpCachingStrategy.ALLOW_ALL`: All request are cacheable if HTTP method is into `allowedMethod`;
106
+ - `NgHttpCachingStrategy.DISALLOW_ALL`: Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`;
107
+
108
+ ### store (class of NgHttpCachingStorageInterface - default: NgHttpCachingMemoryStorage)
109
+ Set the cache store. You can implement your custom store by implement the `NgHttpCachingStorageInterface` interface, eg.:
110
+
111
+ ```ts
112
+ import { NgHttpCachingConfig, NgHttpCachingStorageInterface } from 'ng-http-caching';
113
+
114
+ class MyCustomStore implements NgHttpCachingStorageInterface {
115
+ // ... your logic
116
+ }
117
+
118
+ const ngHttpCachingConfig: NgHttpCachingConfig = {
119
+ store: new MyCustomStore(),
120
+ };
121
+ ```
122
+
123
+ there is also a `withNgHttpCachingLocalStorage` a cache store with persistence into `localStorage`:
124
+
125
+ ```ts
126
+ import { NgHttpCachingConfig, withNgHttpCachingLocalStorage } from 'ng-http-caching';
127
+
128
+ const ngHttpCachingConfig: NgHttpCachingConfig = {
129
+ store: withNgHttpCachingLocalStorage(),
130
+ };
131
+ ```
132
+
133
+ and a `withNgHttpCachingSessionStorage` a cache store with persistence into `sessionStorage`:
134
+
135
+ ```ts
136
+ import { NgHttpCachingConfig, withNgHttpCachingSessionStorage } from 'ng-http-caching';
137
+
138
+ const ngHttpCachingConfig: NgHttpCachingConfig = {
139
+ store: withNgHttpCachingSessionStorage(),
140
+ };
141
+ ```
142
+
143
+ ### isExpired (function - default see NgHttpCachingService.isExpired());
144
+ If this function return `true` the request is expired and a new request is send to backend, if return `false` isn't expired.
145
+ If the result is `undefined`, the normal behaviour is provided.
146
+ Example of customization:
147
+
148
+ ```ts
149
+ import { NgHttpCachingConfig, NgHttpCachingEntry } from 'ng-http-caching';
150
+
151
+ const ngHttpCachingConfig: NgHttpCachingConfig = {
152
+ isExpired: (entry: NgHttpCachingEntry): boolean | undefined => {
153
+ // In this example a special API endpoint (/my-endpoint) send into the body response
154
+ // an expireAt Date property. Only for this endpoint the expiration is provided by expireAt value.
155
+ // For all the other endpoint normal behaviour is provided.
156
+ if( entry.request.urlWithParams.indexOf('/my-endpoint') !== -1 ){
157
+ return entry.response.body.expireAt.getTime() > Date.now();
158
+ }
159
+ // by returning "undefined" normal "ng-http-caching" workflow is applied
160
+ return undefined;
161
+ },
162
+ };
163
+ ```
164
+
165
+ ### isValid (function - default see NgHttpCachingService.isValid());
166
+ If this function return `true` the cache entry is valid and can be stored, if return `false` isn't valid.
167
+ If the result is `undefined`, the normal behaviour is provided.
168
+ Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.
169
+ Example of customization:
170
+
171
+ ```ts
172
+ import { NgHttpCachingConfig, NgHttpCachingEntry } from 'ng-http-caching';
173
+
174
+ const ngHttpCachingConfig: NgHttpCachingConfig = {
175
+ isValid: (entry: NgHttpCachingEntry): boolean | undefined => {
176
+ // In this example only response with status code 200 can be stored into the cache
177
+ return entry.response.status === 200;
178
+ },
179
+ };
180
+ ```
181
+
182
+ ### isCacheable (function - default see NgHttpCachingService.isCacheable());
183
+ If this function return `true` the request is cacheable, if return `false` isn't cacheable.
184
+ If the result is `undefined`, the normal behaviour is provided.
185
+ Example of customization:
186
+
187
+ ```ts
188
+ import { NgHttpCachingConfig } from 'ng-http-caching';
189
+
190
+ const ngHttpCachingConfig: NgHttpCachingConfig = {
191
+ isCacheable: (req: HttpRequest<any>): boolean | undefined => {
192
+ // In this example the /my-endpoint isn't cacheable.
193
+ // For all the other endpoint normal behaviour is provided.
194
+ if( req.urlWithParams.indexOf('/my-endpoint') !== -1 ){
195
+ return false;
196
+ }
197
+ // by returning "undefined" normal "ng-http-caching" workflow is applied
198
+ return undefined;
199
+ },
200
+ };
201
+ ```
202
+
203
+
204
+ ### getKey (function - default see NgHttpCachingService.getKey());
205
+ This function return the unique key (`string`) for store the response into the cache.
206
+ If the result is `undefined`, the normal behaviour is provided.
207
+ Example of customization:
208
+
209
+ ```ts
210
+ import { NgHttpCachingConfig } from 'ng-http-caching';
211
+ import * as hash from 'object-hash'; // install object-hash with: npm i object-hash
212
+
213
+ const hashOptions = {
214
+ algorithm: 'md5',
215
+ encoding: 'hex'
216
+ };
217
+
218
+ const ngHttpCachingConfig: NgHttpCachingConfig = {
219
+ allowedMethod: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD'],
220
+ getKey: (req: HttpRequest<any>): string | undefined => {
221
+ // In this example the full request is hashed for provide an unique key for the cache.
222
+ // This is important if you want support method like POST or PUT.
223
+ return req.method + '@' + req.urlWithParams + '@' + hash(req.params, hashOptions) + '@' + hash(req.body, hashOptions);
224
+ },
225
+ };
226
+ ```
227
+
228
+ ## Headers
229
+
230
+ `NgHttpCaching` use some custom headers for customize the caching behaviour.
231
+ The supported headers are exported from the enum `NgHttpCachingHeaders`:
232
+
233
+ ```ts
234
+ export enum NgHttpCachingHeaders {
235
+ ALLOW_CACHE = 'X-NG-HTTP-CACHING-ALLOW-CACHE',
236
+ DISALLOW_CACHE = 'X-NG-HTTP-CACHING-DISALLOW-CACHE',
237
+ LIFETIME = 'X-NG-HTTP-CACHING-LIFETIME',
238
+ TAG = 'X-NG-HTTP-CACHING-TAG',
239
+ }
240
+ ```
241
+
242
+ All those headers are removed before send the request to the backend.
243
+
244
+ ### X-NG-HTTP-CACHING-ALLOW-CACHE (string: any value);
245
+
246
+ If you have choose the `DISALLOW_ALL` cache strategy, you can mark specific request as cacheable by adding the header `X-NG-HTTP-CACHING-ALLOW-CACHE`, eg.:
247
+
248
+ ```ts
249
+ this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {
250
+ headers: {
251
+ [NgHttpCachingHeaders.ALLOW_CACHE]: '1',
252
+ }
253
+ }).subscribe(e => console.log);
254
+ ```
255
+
256
+ ### X-NG-HTTP-CACHING-DISALLOW-CACHE (string: any value);
257
+
258
+ You can disallow specific request by add the header `X-NG-HTTP-CACHING-DISALLOW-CACHE`, eg.:
259
+
260
+ ```ts
261
+ this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {
262
+ headers: {
263
+ [NgHttpCachingHeaders.DISALLOW_CACHE]: '1',
264
+ }
265
+ }).subscribe(e => console.log);
266
+ ```
267
+
268
+ ### X-NG-HTTP-CACHING-LIFETIME (string: number of millisecond);
269
+
270
+ You can set specific lifetime for request by add the header `X-NG-HTTP-CACHING-LIFETIME` with a string value as the number of millisecond, eg.:
271
+
272
+ ```ts
273
+ this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {
274
+ headers: {
275
+ [NgHttpCachingHeaders.LIFETIME]: (1000 * 60 * 60 * 24 * 365).toString(), // one year
276
+ }
277
+ }).subscribe(e => console.log);
278
+ ```
279
+
280
+ ### X-NG-HTTP-CACHING-TAG (string: tag name);
281
+
282
+ You can tag multiple request by adding special header `X-NG-HTTP-CACHING-TAG` with the same tag and
283
+ using `NgHttpCachingService.clearCacheByTag(tag: string)` for delete all the tagged request. Eg.:
284
+
285
+ ```ts
286
+ this.http.get('https://my-json-server.typicode.com/typicode/demo/db?id=1', {
287
+ headers: {
288
+ [NgHttpCachingHeaders.TAG]: 'foo',
289
+ }
290
+ }).subscribe(e => console.log);
291
+ ```
292
+
293
+ ## HttpContext
294
+
295
+ You can override `NgHttpCachingConfig` methods:
296
+ ```ts
297
+ {
298
+ isExpired?: (entry: NgHttpCachingEntry) => boolean | undefined | void;
299
+ isValid?: (entry: NgHttpCachingEntry) => boolean | undefined | void;
300
+ isCacheable?: (req: HttpRequest<any>) => boolean | undefined | void;
301
+ getKey?: (req: HttpRequest<any>) => string | undefined | void;
302
+ }
303
+ ```
304
+ with `HttpContextToken`, eg.:
305
+ ```ts
306
+ import { withNgHttpCachingContext } from 'ng-http-caching';
307
+
308
+ const context = withNgHttpCachingContext({
309
+ isExpired: (entry: NgHttpCachingEntry) => {
310
+ console.log('context:isExpired', entry);
311
+ },
312
+ isCacheable: (req: HttpRequest<any>) => {
313
+ console.log('context:isCacheable', req);
314
+ },
315
+ getKey: (req: HttpRequest<any>) => {
316
+ console.log('context:getKey', req);
317
+ },
318
+ isValid: (entry: NgHttpCachingEntry) => {
319
+ console.log('context:isValid', entry);
320
+ }
321
+ });
322
+ this.http.get('https://my-json-server.typicode.com/typicode/demo/db?id=1', { context }).subscribe(e => console.log);
323
+ ```
324
+
325
+ ## Cache service
326
+
327
+ You can inject into your component the `NgHttpCachingService` that expose some utils methods:
328
+
329
+ ```ts
330
+ export class NgHttpCachingService {
331
+
332
+ /**
333
+ * Return the config
334
+ */
335
+ getConfig(): Readonly<NgHttpCachingConfig>;
336
+
337
+ /**
338
+ * Return the queue map
339
+ */
340
+ getQueue(): Readonly<Map<string, Observable<HttpEvent<any>>>>;
341
+
342
+ /**
343
+ * Return the cache store
344
+ */
345
+ getStore(): Readonly<NgHttpCachingStorageInterface>;
346
+
347
+ /**
348
+ * Return response from cache
349
+ */
350
+ getFromCache<K, T>(req: HttpRequest<K>): Readonly<HttpResponse<T>> | undefined;
351
+
352
+ /**
353
+ * Add response to cache
354
+ */
355
+ addToCache<K, T>(req: HttpRequest<K>, res: HttpResponse<T>): boolean;
356
+
357
+ /**
358
+ * Delete response from cache
359
+ */
360
+ deleteFromCache<K>(req: HttpRequest<K>): boolean;
361
+
362
+ /**
363
+ * Clear the cache
364
+ */
365
+ clearCache(): void;
366
+
367
+ /**
368
+ * Clear the cache by key
369
+ */
370
+ clearCacheByKey(key: string): boolean;
371
+
372
+ /**
373
+ * Clear the cache by keys
374
+ */
375
+ clearCacheByKeys(keys: Array<string>): number;
376
+
377
+ /**
378
+ * Clear the cache by regex
379
+ */
380
+ clearCacheByRegex<K, T>(regex: RegExp): number;
381
+
382
+ /**
383
+ * Clear the cache by TAG
384
+ */
385
+ clearCacheByTag<K, T>(tag: string): number;
386
+
387
+ /**
388
+ * Run garbage collector (delete expired cache entry)
389
+ */
390
+ runGc<K, T>(): boolean;
391
+
392
+ /**
393
+ * Return true if cache entry is expired
394
+ */
395
+ isExpired<K, T>(entry: NgHttpCachingEntry<K, T>): boolean;
396
+
397
+ /**
398
+ * Return true if cache entry is valid for store in the cache
399
+ * Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.
400
+ */
401
+ isValid<K, T>(entry: NgHttpCachingEntry<K, T>): boolean;
402
+
403
+ /**
404
+ * Return true if the request is cacheable
405
+ */
406
+ isCacheable<K>(req: HttpRequest<K>): boolean;
407
+
408
+ /**
409
+ * Return the cache key.
410
+ * Default key is http method plus url with query parameters, eg.:
411
+ * `GET@https://github.com/nigrosimone/ng-http-caching`
412
+ */
413
+ getKey<K>(req: HttpRequest<K>): string;
414
+
415
+ /**
416
+ * Return observable from cache
417
+ */
418
+ getFromQueue<K, T>(req: HttpRequest<K>): Observable<HttpEvent<T>> | undefined;
419
+
420
+ /**
421
+ * Add observable to cache
422
+ */
423
+ addToQueue<K, T>(req: HttpRequest<K>, obs: Observable<HttpEvent<T>>): void;
424
+
425
+ /**
426
+ * Delete observable from cache
427
+ */
428
+ deleteFromQueue<K>(req: HttpRequest<K>): boolean;
429
+ }
430
+ ```
431
+
432
+ ## Examples
433
+
434
+ Below there are some examples of use case.
435
+
436
+ ### Example: exclude specific request from cache
437
+
438
+ You can disallow specific request by add the header `X-NG-HTTP-CACHING-DISALLOW-CACHE`, eg.:
439
+
440
+ ```ts
441
+ import { Component, OnInit } from '@angular/core';
442
+ import { HttpClient } from "@angular/common/http";
443
+ import { NgHttpCachingHeaders } from 'ng-http-caching';
444
+
445
+ @Component({
446
+ selector: 'app-root',
447
+ templateUrl: './app.component.html',
448
+ styleUrls: ['./app.component.scss']
449
+ })
450
+ export class AppComponent implements OnInit {
451
+
452
+ constructor(private http: HttpClient) {}
453
+
454
+ ngOnInit(): void {
455
+ // This request will never cache.
456
+ // Note: all the "special" headers in NgHttpCachingHeaders are removed before send the request to the backend.
457
+ this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {
458
+ headers: {
459
+ [NgHttpCachingHeaders.DISALLOW_CACHE]: '1',
460
+ }
461
+ }).subscribe(e => console.log);
462
+ }
463
+ }
464
+ ```
465
+
466
+ ### Example: set specific lifetime for request
467
+
468
+ You can set specific lifetime for request by add the header `X-NG-HTTP-CACHING-LIFETIME` with a string value as the number of millisecond, eg.:
469
+
470
+ ```ts
471
+ import { Component, OnInit } from '@angular/core';
472
+ import { HttpClient } from "@angular/common/http";
473
+ import { NgHttpCachingHeaders } from 'ng-http-caching';
474
+
475
+ @Component({
476
+ selector: 'app-root',
477
+ templateUrl: './app.component.html',
478
+ styleUrls: ['./app.component.scss']
479
+ })
480
+ export class AppComponent implements OnInit {
481
+
482
+ constructor(private http: HttpClient) {}
483
+
484
+ ngOnInit(): void {
485
+ // This request will expire from 365 days.
486
+ // Note: all the "special" headers in NgHttpCachingHeaders are removed before send the request to the backend.
487
+ this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {
488
+ headers: {
489
+ [NgHttpCachingHeaders.LIFETIME]: (1000 * 60 * 60 * 24 * 365).toString(),
490
+ }
491
+ }).subscribe(e => console.log);
492
+ }
493
+ }
494
+ ```
495
+
496
+ ### Example: mark specific request as cacheable (if cache strategy is DISALLOW_ALL)
497
+
498
+ If you have choose the `DISALLOW_ALL` cache strategy, you can mark specific request as cacheable by adding the header `X-NG-HTTP-CACHING-ALLOW-CACHE`, eg.:
499
+
500
+ ```ts
501
+ import { Component, OnInit } from '@angular/core';
502
+ import { HttpClient } from "@angular/common/http";
503
+ import { NgHttpCachingHeaders } from 'ng-http-caching';
504
+
505
+ @Component({
506
+ selector: 'app-root',
507
+ templateUrl: './app.component.html',
508
+ styleUrls: ['./app.component.scss']
509
+ })
510
+ export class AppComponent implements OnInit {
511
+
512
+ constructor(private http: HttpClient) {}
513
+
514
+ ngOnInit(): void {
515
+ // This request is marked as cacheable (this is necessary only if cache strategy is DISALLOW_ALL)
516
+ // Note: all the "special" headers in NgHttpCachingHeaders are removed before send the request to the backend.
517
+ this.http.get('https://my-json-server.typicode.com/typicode/demo/db', {
518
+ headers: {
519
+ [NgHttpCachingHeaders.ALLOW_CACHE]: '1',
520
+ }
521
+ }).subscribe(e => console.log);
522
+ }
523
+ }
524
+ ```
525
+
526
+ ### Example: clear/flush all the cache
527
+
528
+ If user switch the account (logout/login) or the application language, maybe ca be necessary clear all the cache, eg.:
529
+
530
+ ```ts
531
+ import { Component } from '@angular/core';
532
+ import { NgHttpCachingService } from 'ng-http-caching';
533
+
534
+ @Component({
535
+ selector: 'app-root',
536
+ templateUrl: './app.component.html',
537
+ styleUrls: ['./app.component.scss']
538
+ })
539
+ export class AppComponent {
540
+
541
+ constructor(private ngHttpCachingService: NgHttpCachingService) {}
542
+
543
+ clearCache(): void {
544
+ // Clear all the cache
545
+ this.ngHttpCachingService.clearCache();
546
+ }
547
+ }
548
+ ```
549
+
550
+ ### Example: clear/flush specific cache entry
551
+
552
+ If you want delete some cache entry, eg.:
553
+
554
+ ```ts
555
+ import { Component } from '@angular/core';
556
+ import { NgHttpCachingService } from 'ng-http-caching';
557
+
558
+ @Component({
559
+ selector: 'app-root',
560
+ templateUrl: './app.component.html',
561
+ styleUrls: ['./app.component.scss']
562
+ })
563
+ export class AppComponent {
564
+
565
+ constructor(private ngHttpCachingService: NgHttpCachingService) {}
566
+
567
+ clearCache(key: string): boolean {
568
+ // Clear the cache for the provided key
569
+ return this.ngHttpCachingService.clearCacheByKey(key);
570
+ }
571
+ }
572
+ ```
573
+
574
+ ### Example: clear/flush specific cache entry by RegEx
575
+
576
+ If you want delete some cache entry by RegEx, eg.:
577
+
578
+ ```ts
579
+ import { Component } from '@angular/core';
580
+ import { NgHttpCachingService } from 'ng-http-caching';
581
+
582
+ @Component({
583
+ selector: 'app-root',
584
+ templateUrl: './app.component.html',
585
+ styleUrls: ['./app.component.scss']
586
+ })
587
+ export class AppComponent {
588
+
589
+ constructor(private ngHttpCachingService: NgHttpCachingService) {}
590
+
591
+ clearCacheByRegex(regEx: RegExp): void {
592
+ // Clear the cache for the key that match regex
593
+ this.ngHttpCachingService.clearCacheByRegex(regEx);
594
+ }
595
+ }
596
+ ```
597
+
598
+ ### Example: TAG request and clear/flush specific cache entry by TAG
599
+
600
+ You can tag multiple request by adding special header `X-NG-HTTP-CACHING-TAG` with the same tag and
601
+ using `NgHttpCachingService.clearCacheByTag(tag:
602
+ )` for delete all the tagged request. Eg.:
603
+
604
+ ```ts
605
+ import { Component, OnInit } from '@angular/core';
606
+ import { HttpClient } from "@angular/common/http";
607
+ import { NgHttpCachingService } from 'ng-http-caching';
608
+
609
+ @Component({
610
+ selector: 'app-root',
611
+ templateUrl: './app.component.html',
612
+ styleUrls: ['./app.component.scss']
613
+ })
614
+ export class AppComponent {
615
+
616
+ constructor(private ngHttpCachingService: NgHttpCachingService) {}
617
+
618
+ ngOnInit(): void {
619
+ // This request is tagged with "foo" keyword. You can tag multiple requests with the same tag and
620
+ // using NgHttpCachingService.clearCacheByTag("foo") for delete all the tagged request.
621
+ this.http.get('https://my-json-server.typicode.com/typicode/demo/db?id=1', {
622
+ headers: {
623
+ [NgHttpCachingHeaders.TAG]: 'foo',
624
+ }
625
+ }).subscribe(e => console.log);
626
+
627
+ // This request is also tagged with "foo" keyword, and has another tag "baz".
628
+ // You can add multiple tags comma separated.
629
+ this.http.get('https://my-json-server.typicode.com/typicode/demo/db?id=2', {
630
+ headers: {
631
+ [NgHttpCachingHeaders.TAG]: 'foo,baz',
632
+ }
633
+ }).subscribe(e => console.log);
634
+ }
635
+
636
+ clearCacheForFoo(): void {
637
+ // Clear the cache for all the entry have the tag 'foo'
638
+ this.ngHttpCachingService.clearCacheByTag('foo');
639
+ }
640
+ }
641
+ ```
642
+
643
+ ## Alternatives
644
+
645
+ Aren't you satisfied? there are some valid alternatives:
646
+
647
+ - [@ngneat/cashew](https://www.npmjs.com/package/@ngneat/cashew)
648
+ - [p3x-angular-http-cache-interceptor](https://www.npmjs.com/package/p3x-angular-http-cache-interceptor)
649
+ - [@d4h/angular-http-cache](https://www.npmjs.com/package/@d4h/angular-http-cache)
650
+
651
+
652
+ ## Support
653
+
654
+ This is an open-source project. Star this [repository](https://github.com/nigrosimone/ng-http-caching), if you like it, or even [donate](https://www.paypal.com/paypalme/snwp). Thank you so much!
655
+
656
+ ## My other libraries
657
+
658
+ I have published some other Angular libraries, take a look:
659
+
660
+ - [NgSimpleState: Simple state management in Angular with only Services and RxJS](https://www.npmjs.com/package/ng-simple-state)
661
+ - [NgGenericPipe: Generic pipe for Angular application for use a component method into component template.](https://www.npmjs.com/package/ng-generic-pipe)
662
+ - [NgLet: Structural directive for sharing data as local variable into html component template](https://www.npmjs.com/package/ng-let)
663
+ - [NgForTrackByProperty: Angular global trackBy property directive with strict type checking](https://www.npmjs.com/package/ng-for-track-by-property)