DEV Community

Nigro Simone
Nigro Simone

Posted on

Smart HTTP Caching in Angular with NgHttpCaching

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:

  1. Checks if a valid cached response exists
  2. If yes → returns it immediately
  3. If no → sends the request to the backend
  4. 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-control and expires headers
  • ✅ Fully configurable

⚡ Installation

npm i ng-http-caching
Enter fullscreen mode Exit fullscreen mode

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())
  ]
});
Enter fullscreen mode Exit fullscreen mode

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'],
};
Enter fullscreen mode Exit fullscreen mode

Then:

provideNgHttpCaching(config)
Enter fullscreen mode Exit fullscreen mode

🧠 Smart Cache Invalidation on Mutations

Caching is easy. Keeping it consistent is not.

NgHttpCaching includes automatic mutation invalidation strategies:

clearCacheOnMutation: NgHttpCachingMutationStrategy.COLLECTION
Enter fullscreen mode Exit fullscreen mode

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')
Enter fullscreen mode Exit fullscreen mode

💾 Persistent Storage

Default storage is in-memory.

But you can switch to:

LocalStorage

import { withNgHttpCachingLocalStorage } from 'ng-http-caching';

provideNgHttpCaching({
  store: withNgHttpCachingLocalStorage()
});
Enter fullscreen mode Exit fullscreen mode

SessionStorage

import { withNgHttpCachingSessionStorage } from 'ng-http-caching';
Enter fullscreen mode Exit fullscreen mode

Custom Store

Implement NgHttpCachingStorageInterface and plug in your own logic.


🏷 Tag-Based Cache Management

You can tag requests:

headers: {
  [NgHttpCachingHeaders.TAG]: 'users'
}
Enter fullscreen mode Exit fullscreen mode

Then clear them later:

ngHttpCachingService.clearCacheByTag('users');
Enter fullscreen mode Exit fullscreen mode

Perfect for domain-specific invalidation scenarios.


🎯 Per-Request Overrides

You can control caching behavior via headers:

  • X-NG-HTTP-CACHING-ALLOW-CACHE
  • X-NG-HTTP-CACHING-DISALLOW-CACHE
  • X-NG-HTTP-CACHING-LIFETIME
  • X-NG-HTTP-CACHING-TAG

Or override configuration methods using HttpContext.

You can customize:

  • isExpired
  • isValid
  • isCacheable
  • getKey

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);
}
Enter fullscreen mode Exit fullscreen mode

Now even mutation requests can be uniquely cached.


🧹 Manual Cache Control

Inject NgHttpCachingService:

constructor(private cache: NgHttpCachingService) {}
Enter fullscreen mode Exit fullscreen mode

Available methods:

  • clearCache()
  • clearCacheByKey()
  • clearCacheByRegex()
  • clearCacheByTag()
  • runGc()
  • getFromCache()

Full control when you need it.


📦 Live Demo

Try it here:

https://stackblitz.com/edit/demo-ng-http-caching-21

Top comments (0)