Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Part 1 Update. #2

Open
ezzabuzaid opened this issue Jun 3, 2021 · 0 comments
Open

Part 1 Update. #2

ezzabuzaid opened this issue Jun 3, 2021 · 0 comments

Comments

@ezzabuzaid
Copy link
Owner

ezzabuzaid commented Jun 3, 2021

Angular API Caching

Update (Date Here): change the implementation to use localForage library.

This article will take you through the way to efficiently handle the HTTP client request and cache them inside different browser storage.

For clarity about what I’m going to talk about, the full project is available to browse through Github.

What Is Caching

Caching is a way to store data that is often in use (HTTP response in our case) in storage to quickly access it later on. So instead of asking for the same data twice, you store a copy of it, and later on, you got that copy instead of the original.

How It Works

  1. A request made to server X to get data Y.
  2. The request goes through the cache to check if there's a copy from point 4.
  3. No copy found so the request will be delegated to the actual server. otherwise, jump to point 5.
  4. The server returned data Y and pass a copy through the cache.
  5. The request initiator gets the data to deal with it.
  6. Data will remain in cache till it expires or the cache is cleared.

That is the basic flow of how cache works.

There're many advantages of caching in general so I'll just point out some of what the Front End interested in

When/Why To Use Cache

  • Reduce the number of requests.
  • Store response that doesn't frequently change.
  • Request that the application addressing frequently.
  • Improve responsiveness by retrieving the response immediately.
  • Show some content while you requesting the fresh content.
  • Show some data while there's no internet connection to provide an offline experience

And of course, there might be other use cases depends on your custom usage.

Where To Store The Cache Data

  1. LocalStorage
  2. SessionStorage
  3. IndexedDB
  4. WebSql
  5. Cache API
  6. Cookie
  7. And InMemory 😁

We will use localForage library that acts as one interface for most of the mentioned storages, of course, you can use whatever you see suitable.

you can install from here npm install localforage

Example Usage

import { Injectable } from '@angular/core';
import { HttpClient, HttpResponse } from '@angular/common/http';

@Injectable()
export class ExampleService {

    constructor(
        private httpClient: HttpClient,
    ) { }

    getData() {
        const url = '/endpoint-url';
        return this.httpClient.get(url);
    }

}

Sample showing an example service that gets data from a server

import * as localforage from 'localforage';
const store = localforage.createInstance({
    driver: localforage.INDEXEDDB, /** Here where you can change the storage */
    version: 1.0,
    storeName: 'cache',
});

Configure a store, I'm using IndexedDB but feel free to use anything else.


Going back to the start.

  1. Initiate a request to server X to get data Y. (the request initiator is getData method )
  2. The request goes through the cache to check if there's a copy from point 4.
  3. No copy found so the request will be delegated to the actual server. otherwise, jump to point 5.
  4. The server returned data Y and pass a copy through the cache.
  5. The request initiator gets the data to deal with it.
  6. Data will remain in cache till it expires or the cache is cleared.
getData() {
    const url = 'https://jsonplaceholder.typicode.com/todos/1';
    return defer(() => store.getItem(url) /** step 2 */)
        .pipe(switchMap((cachedData) => {
            if (cachedData === null || cachedData === undefined) { /** step 3 */
                return this.httpClient.get(url) /** step 1 */
                    .pipe(switchMap((newData) => store.setItem(url, newData)));
            }
            return of(cachedData); /** step 5 */
        }))
}

defer used to create an Observable from Promise.

More about caching.

Caching Strategy

You might not want always to return the data from the cache perhaps you want only to hit the cache if the server call failed in this case you have something to show to the user or you want to hit the cache and the server so you have something to present quickly from the cache in the same time you're getting the fresh data from the server.

  1. Cache First (Cache Falling Back to Network)
    This implies that the cache has a higher priority to fetch data from. what we already did above.

  2. Network First (Network Falling Back to Cache)
    As opposite, fetch data from the network and if an error occurred or no internet connection use cache as a fallback

  3. Stale-While-Revalidate
    Return data from the cache while fetching the new data from the server.

Read more on web.dev

Resources
https://web.dev/service-worker-caching-and-http-caching/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant