How do I sync data with remote database in case of offline-first applications?

后端 未结 2 2083
一生所求
一生所求 2021-02-03 10:02
  • I am building a \"TODO\" application which uses Service Workers to cache the request\'s responses and in case a user is offline, the cached data is displayed to the user.
2条回答
  •  太阳男子
    2021-02-03 10:36

    What patterns are in use to sync the pending requests with the REST-ful Server when the connection is back online?

    Background Sync API will be suitable for this scenario. It enables web applications to synchronize data in the background. With this, it can defer actions until the user has a reliable connection, ensuring that whatever the user wants to send is actually sent. Even if the user navigates away or closes the browser, the action is performed and you could notify the user if desired.

    Since you're saving to IndexDB, you could register for a sync event when the user add, delete or update a TODO item

    function addTodo(todo) {
      return addToIndeDB(todo).then(() => {
        // Wait for the scoped service worker registration to get a
        // service worker with an active state
        return navigator.serviceWorker.ready;
      }).then(reg => {
        return reg.sync.register('add-todo');
      }).then(() => {
        console.log('Sync registered!');
      }).catch(() => {
        console.log('Sync registration failed :(');
      });
    }
    

    You've registered a sync event of type add-todo which you'll listen for in the service-worker and then when you get this event, you retrieve the data from the IndexDB and do a POST to your Restful API.

    self.addEventListener('sync', event => {
    if (event.tag == 'add-todo') {
          event.waitUntil(
          getTodo().then(todos => {
            // Post the messages to the server
            return fetch('/add', {
              method: 'POST',
              body: JSON.stringify(todos),
              headers: { 'Content-Type': 'application/json' }
            }).then(() => {
              // Success!
            });
          })
          })
        );
       }
    });
    

    This is just an example of how you could achieve it using Background Sync. Note that you'll have to handle conflict resolution on the server.

    You could use PouchDB on the client and Couchbase or CouchDB on the server. With PouchDB on the client, you can save data on the client and set it to automatically sync/replicate the data whenever the user is online. When the database synchronizes and there are conflicting changes, CouchDB will detect this and will flag the affected document with the special attribute "_conflicts":true. It determines which one it'll use as the latest revision, and save the others as the previous revision of that record. It does not attempt to merge the conflicting revision. It is up to you to dictate how the merging should be done in your application. It's not so different from Couchbase too. See the links below for more on Conflict Resolution.

    • Conflict Management with CouchDB
    • Understanding CouchDB Conflict
    • Resolving Couchbase Conflict
    • Demystifying Conflict Resolution in Couchbase Mobile

    I've used pouchDB and couchbase/couchdb/IBM cloudant but I've done that through Hoodie It has user authentication out-of-the box, handles conflict management, and a few more. Think of it like your backend. In your TODO application, Hoodie will be a great fit. I've written something on how to use Hoodie, see links Below:

    • How to build offline-smart application with Hoodie
    • Introduction to offline data storage and sync with PouchBD and Couchbase

提交回复
热议问题