Architecture for Online-Offline Web Application

Architectureofflineweb

I have a data-driven legacy system (has a Java Swing client and a JavaEE application server) in my workplace, This system uses a single database for querying and modifying data.

Recently we've been asked to write a new web application that implements some of the already-existing features of the legacy system.

The application should work both online and offline – offline times can be for an hour or so but might as well be for a few minutes.

This is what we thought to implement for offline only functionality:

  • Using Service Worker to store static app files (so we could access it when offline).
  • Fetching data when going to offline mode and storing it inside the local db.
  • Reading from the local db (IndexedDB).
  • Performed operations will reside in the local database in a queue form.
  • Syncing back performed operations from the queue when going back online (as a one batch, some actions may have a dependency on others).

To let the application be as general as possible and prevent repeating offline/online checks, we thought about this solution for adding online functionality:

  • Requests to fetch data (upon page or component load) will go to the remote server and update the local database, which will be requested afterwards.
  • Performed operations will be added to the operations queue (same as the offline one).
  • Polling the queue and invoking the remote server, updating the client in an async manner.

Assume that only one client can update a certain set of data, so no server-side synchronization problems here.

Is this a maintainable and scalable approach ?

There is also another consideration here – the REST api that the server exposes.
If i use the same api for batching operations and single operations, it should be a general api that accepts different types of actions, command-like principle.

I didn't hear much about this kind of service which leads me to think this isn't a good REST design, is there another way of implementing it?

Best Answer

You know your system the best - requirements and limitations. Here are some general things which I would consider when planning architecture of such a system:

1) Would you like to perform some operations on client side (and duplicating business logic) or you want to perform business logic only on the server? E.g In the offline mode I created order but then decided to cancel.
2) How time consuming can be replaying all actions when back to online mode? Should other actions be blocked then? Or maybe you want to queue them when synchronization is in progress. E.g. Let's assume that I created 100 orders. When I go online again synchronization starts. Now I want to cancel one order but I can't do it because there is possibly cancel action already on the queue.
3) Regarding REST endpoint - it can be simply as

/synchronization-queue { actions : [{ type : "ORDER_CREATED", ...}, {...}, {...}, ...]

4) Depending on your use case you can consider using Event Sourcing (but think twice before)
5) Do you plan to update client application frequently?
6) Are there any critical operations which can't be performed offline? How do they affect other actions?
7) If there is no synchronization problem and access to your resources is exclusive per client application then you always only need to sync from client to server (unless the same client can use e.g. other device)
8) Some operations may require confirmation from the server. You need to identify these operations and decide if they can be considered successful even without server confirmation.
And much more...

Related Topic