Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

From a network dependent web app to an network independant web app

I'm a full stack web developer and currently I'm mostly building single page app using front end framework such as angular and backend framework such as spring boot.

Usually the design of my web app (let's say it's a CRUD) is as follow : Let's say I'm on the update page and I update an entity. Then a request is made to the backend that update the entity in the database. When the backend respond saying everything is alright your entity has been updated (status code 200) I go through the next page which is the read page with an url such as entityName/{id} where I pass the id of the entity to the next page through the url. Then on the read page I get that id, make a request to the backend, retrieve the entity data and display them.

The problem arise when the user lost the connectivity to the internet, so the request to the backend can not be made and consequently data cannot be displayed to the ui or be updated.

An other design would be this one : I'm on the update page and I update my entity. A request is made to the backend but also the state is being kept on the client side. So let's say the connectivity is lost I still can go to the read page and display the updated entity. Moreover as the state / data is kept on the client side I don't have to make that second request to the backend to get the entity from the id since the entity lives on the client side. During the time the user spent on the app the connectivity comes back and the update request is made to the server to synchronize the data in the db and on the client side.

It would seem to me that the second approach is more convenient for the user since the ui does not rely as much on the request made to the backend to display its information making it more fluent and more agreeable.

I very well know that the first approach is in use. I develop like this and so my question is : Is it possible to go from the first design to the second design and if yes with what technologies ?

What I would do to implement the second design would be to share data across components using services (when implementing with angular). In this way the state of the app can be kept on the client side. But maybe there is a better way. I heard about the NgRx library to manage the state of an application. Is it the right way to go to manage the state of the application on the client side ?

Also there is a second problem that is to make sure that the requests that could not be made when the connectivity was lost is made when the connectivity is back. And so I wonder : Is it possible to use a tool that enable to queue the requests and rerun them when the connectivity is back ? I have notion of progressive web app and service workers but only notion (like I know that a service worker can be used to cache data exchanged with the server) and I wonder if it is a way to solve this problem ?

I'm waiting for your comments on my post. I hope it was not too long. Thanks in advance.

like image 798
Vetouz Avatar asked Jan 23 '20 17:01

Vetouz


1 Answers

Moreover as the state / data is kept on the client side I don't have to make that second request to the backend to get the entity from the id since the entity lives on the client side

This depends entirely on how much you can trust the BE. If an error occurs for whatever reason (expired token/signed out? Data updated on another client?) this approach can become significantly more complicated.

Is it possible to go from the first design to the second design and if yes with what technologies?

Potentially you can make your app a PWA and use service workers. I found a good guide for this here. In case the blog goes down, it goes through the caching of assets and fonts in the ngsw-config.json, then it touches up on API caching. Here's what the final result might look like:

{
  "$schema": "./node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/manifest.webmanifest",
          "/*.css",
          "/*.js"
        ]
      }
    }, {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "resources": {
        "files": [
          "/assets/**",
          "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
        ]
      }
    }
  ],
  "dataGroups": [{
    "name": "api-freshness",
    "urls": [
      "/timeline"
    ],
    "cacheConfig": {
      "strategy": "freshness",
      "maxSize": 100,
      "maxAge": "3d",
      "timeout": "10s"
    }
  },
    {
      "name": "api-performance",
      "urls": [
        "/favorites"
      ],
      "cacheConfig": {
        "strategy": "performance",
        "maxSize": 100,
        "maxAge": "3d"
      }
    }
  ]
}

"For network-first strategy, it’s freshness, for cache-first — performance"

Is it the right way to go to manage the state of the application on the client side ?

You can use NgRx to cache your app data, but you'll need to make sure that the cache is always up to date. Ideally, you use some a websocket to detect BE changes, but you could also potentially do polling.

However if all you need is offline functionality, PWAs feel like the way to go.

Is it possible to use a tool that enable to queue the requests and rerun them when the connectivity is back?

This feature is called background sync and is a feature of service workers. That being said, I found this open issue on it. You could try this but it feels like a hack. If it were up to me, I'd create an array of observables which are called when the connection comes back until there's better pwa support for this

like image 112
Gabrielus Avatar answered Nov 13 '22 13:11

Gabrielus