How to cache Angular HTTP requests (4 best ways)


Here's how to cache HTTP requests.

When you use Angular's HTTP client (and RxJS).

So you want to do some caching?

And cache the HTTP requests that your Angular app is making?

There are different ways to do it, buster.

Sometimes you'll need to retry an HTTP Angular request or monitor the slowness of HTTP requests.

But in this article I'm going to reveal the 4 best ways to cache Angular HTTP requests that I know of.

So how do we do caching in Angular?

How to cache API calls in Angular?

Ready?

Here's how to kick a cache.

Table of Contents

1. How to cache HTTP requests with a service worker

One of Angular's slick features is the ability to turn your Angular project into a PWA (Progress Web App) with one command.

This will install a service worker and configure it to cache the static parts of your Angular app.

But that's not all a service worker can do.

It can be configured to cache API requests as well.

The first step is to install the @angular/pwa package.

ng add @angular/pwa 

When you install this package it will make a few changes.

  • Adds @angular/service-worker as a dependency.
  • Enables service worker builds in the Angular CLI.
  • Imports and registers the service worker in the app module.
  • Adds a web app manifest.
  • Updates the index.html file to link to the manifest and set theme colors.
  • Adds required icons for the manifest.
  • Creates a config file ngsw-config.json, specifying caching behaviors and other settings.

Now that we've turned our Angular application into a PWA we can start caching API requests. There are far more caching options available then what I can explain now but here's how to get started.

Open the new ngsw-config.json file. You can find it in the root directory of your Angular project.

You'll want to begin by defining a new section called dataGroups which will be an array of cache configs for our data resources (e.g. API).

Here's an example with one cache config defined. You can add as many as you want inside the dataGroups array.

"dataGroups": [
    {
      "name": "api",
      "urls": [
        "/api/**"
      ],
      "cacheConfig": {
        "maxSize": 5000,
        "maxAge": "5m",
        "strategy": "performance"
      }
    }
 ]

Inside the new config we define a name and URLs that this cache configuration applies to.

Here are 3 important things you need to know about caching and Angular service workers.

  • This will only cache GET and HEAD requests.
  • The caching rules are processed in the order that they appear. That's why it's recommended that to put the more specific groups at the top of the list.
  • You cannot test service workers in development environment. You have to build production and then test.

2. How to cache HTTP requests with NgHttpCaching.

The NgHttpCaching package does about the same thing that an Angular service worker does.

It intercepts all the HTTP request that are made, tries to retrieve a cached instance of the response and then return the cached response. Otherwise, it will send the request to the API and when a response is received it will cache it for next time.

Here's how you install it.

npm i ng-http-caching --save

Once installed, open the app.module.ts file and add the needed imports to the top of the file. You'll also need to declare a NgHttpCachingConfig variable to store your desired caching config.

Here's an example.

import { NgHttpCachingModule, NgHttpCachingConfig } from 'ng-http-caching';

const ngHttpCachingConfig: NgHttpCachingConfig = {
  lifetime: 1000 * 60, // cache expire after 60 seconds,
  allowedMethod: ['GET', 'HEAD'],
  cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,
};

And then the final step is to register the NgHttpCachingModule inside the imports.

  imports: [
    HttpClientModule,
    NgHttpCachingModule.forRoot(ngHttpCachingConfig),
  ],

If you're interested in all its caching options then check out the docs here.

3. How to cache with cashew

The difference between cashew and httpcache is that cashew is per-http request instead of a global cache.

npm i @ngneat/cashew

Import into your module

import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { HttpCacheInterceptorModule } from '@ngneat/cashew';

@NgModule({
  imports: [HttpClientModule, HttpCacheInterceptorModule.forRoot()],
  bootstrap: [AppComponent]
})
export class AppModule {}

Usage:

import { withCache } from '@ngneat/cashew';

@Injectable()
export class UsersService {
  constructor(private http: HttpClient) {}

  getUsers() {
    return this.http.get('api/users', {
      context: withCache()
    });
  }
}

4. How to create your own basic custom cache

Assuming you have an HTTP service, here's what the code looks like.

private customers$: Observables<Customer[]>;

public getCustomers(): Observable<Customer[]> {
  if(!this.customers) {
    this.customers = this.http.get("https://myapiserver.com/api/customers");
  }
  return this.customers$;
}

If the cache is null then we initialize it with data from the API server. And then after that we respond with the data inside of the cache.

Conclusion

And that, my friend is the 4 different ways to add caching to your Angular app.

Of course, there are more than 4 ways to do this but these are the 4 best approaches that I know of.

Which approach are you using? Or maybe you know of a better one? Let me know in the comments below.

signature

Angular Consultant