Letβs be honest: how many times does your Angular app hit the same endpoint over and over again?
- Multiple components requesting the same data
- Identical parallel requests
- Users navigating back and forth between routes
- The same service invoked multiple times
Result: unnecessary backend load and wasted latency.
NgHttpCaching solves this problem in a clean and predictable way.
Itβs an Angular HTTP interceptor that adds configurable, intelligent caching to your HttpClient without changing your architecture.
π How It Works
NgHttpCaching intercepts outgoing HTTP requests and:
- Checks if a valid cached response exists
- If yes β returns it immediately
- If no β sends the request to the backend
- When the response arrives β stores it in cache
It also automatically handles simultaneous requests to the same endpoint:
only one real HTTP call is made, and the others subscribe to the same observable.
Clean. Efficient. Deterministic.
β¨ Key Features
- β HTTP caching via interceptor
- β Handles simultaneous/parallel requests
- β Automatic garbage collector for expired entries
- β Automatic cache invalidation on mutations (POST, PUT, DELETE, PATCH)
- β MemoryStorage, LocalStorage, SessionStorage or custom store
- β
Optional support for
cache-controlandexpiresheaders - β Fully configurable
β‘ Installation
npm i ng-http-caching
With Angular standalone:
import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { provideNgHttpCaching } from 'ng-http-caching';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent, {
providers: [
provideNgHttpCaching(),
provideHttpClient(withInterceptorsFromDi())
]
});
Thatβs it. Your GET requests are now cached.
π§ Configuration
Everything is optional and customizable.
import { NgHttpCachingConfig } from 'ng-http-caching';
const config: NgHttpCachingConfig = {
lifetime: 1000 * 10, // 10 seconds
allowedMethod: ['GET', 'HEAD'],
};
Then:
provideNgHttpCaching(config)
π§ Smart Cache Invalidation on Mutations
Caching is easy. Keeping it consistent is not.
NgHttpCaching includes automatic mutation invalidation strategies:
clearCacheOnMutation: NgHttpCachingMutationStrategy.COLLECTION
Available strategies:
-
NONEβ No automatic invalidation -
ALLβ Clear the entire cache -
IDENTICALβ Clear entries with the same URL -
COLLECTIONβ Clear resource and its parent collection - Custom function β Fully custom logic
Example:
clearCacheOnMutation: (req) => req.url.includes('/api/critical-data')
πΎ Persistent Storage
Default storage is in-memory.
But you can switch to:
LocalStorage
import { withNgHttpCachingLocalStorage } from 'ng-http-caching';
provideNgHttpCaching({
store: withNgHttpCachingLocalStorage()
});
SessionStorage
import { withNgHttpCachingSessionStorage } from 'ng-http-caching';
Custom Store
Implement NgHttpCachingStorageInterface and plug in your own logic.
π· Tag-Based Cache Management
You can tag requests:
headers: {
[NgHttpCachingHeaders.TAG]: 'users'
}
Then clear them later:
ngHttpCachingService.clearCacheByTag('users');
Perfect for domain-specific invalidation scenarios.
π― Per-Request Overrides
You can control caching behavior via headers:
X-NG-HTTP-CACHING-ALLOW-CACHEX-NG-HTTP-CACHING-DISALLOW-CACHEX-NG-HTTP-CACHING-LIFETIMEX-NG-HTTP-CACHING-TAG
Or override configuration methods using HttpContext.
You can customize:
isExpiredisValidisCacheablegetKey
Even per request.
π Advanced Example: Safe POST Caching
By default, cache key = METHOD@URL_WITH_PARAMS.
If you want to cache POST/PUT safely, define a custom key:
getKey: (req) => {
return req.method + '@' +
req.urlWithParams + '@' +
JSON.stringify(req.body);
}
Now even mutation requests can be uniquely cached.
π§Ή Manual Cache Control
Inject NgHttpCachingService:
constructor(private cache: NgHttpCachingService) {}
Available methods:
clearCache()clearCacheByKey()clearCacheByRegex()clearCacheByTag()runGc()getFromCache()
Full control when you need it.
π¦ Live Demo
Try it here:
Top comments (0)