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)