Recently, I’ve delved back into Angular on a new project for the first time since the Angular 1.x days. The new Angular seems familiar yet much more robust and productive since embracing object-oriented programming principles.
One requirement I had was to implement a simple request cache as data from the API I am consuming doesn’t change too frequently. I initially approached the problem with a simple solution but soon found some documentation related to the relatively new HttpClient API. HttpClient also supports registering an interceptor – a similar pattern to middleware in a modern webserver – via the HttpInterceptor interface. And to my delight, they even included a caching example using the aforementioned tools.
Since the example provided left some bits to the imagination, I’ve included a complete example in this guide.
First, we have our subclass of
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
intercept is invoked any time a request is made. First, we try to retrieve a cached instance of the response from our cache (we’ll look at this in a moment) and then we either return the cached response or we pass along the request to executed by calling
sendRequest. Then, once
sendRequest is invoked, it calls
next to execute the next operation (similar to the middleware pattern). Once the operation has completed we cache the response. In this example we are using a hard-coded cache time of 10 seconds for simplicity.
I can imagine it would be possible to create a subclass of HttpClient in order to facilitate setting different TTLs on a per-request basis as well but I won’t get into that here.
Ok, so what about the cache? The cache is provided by a separate service called
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
The cache is fairly simple. We have two instance methods:
set. The first takes a key and returns a value unless it’s expired. The second takes a key, value, and time-to-live – or ttl – and stores the data in a Map. We use an in-memory Map here for storage, but you could use anything you need here to store the data. LocalStorage, for instance, would be suitable for longer term storage.
With these two components, we have everything we need for a simple request caching interceptor in our Angular application.
Don’t forget to provide the components to the dependency injector tree so that the cache service is available and the interceptor is registered to intercept http requests. Providing an HttpInterceptor is fairly involved but there are good instructions on how to do that here.
For anyone investigating Angular HttpInterceptors for the first time, I hope this guide is helpful.