Architecture of an app when using CouchDB/PouchDB

1.5k views Asked by At

I am wondering how the architecture should look like when using PouchDB as a local storage in a mobile app instead of localStorage.

At this moment I am used to cache my app's data into localStorage and when needed I perform an API call to the backend to request or post data. The backend is holding all logic. Such as:

  • Does this user has the correct permission/role to do this action?
  • Any other logic needed to check if action can be done

All data is then stored into a relational database. I have now been reading about NoSQL databases and in particular CouchDB and PouchDB. So I am wondering how would this architecture look like? Three questions arise at this point for me:

  1. If I have multiple users with there own authentication, how can I make sure that the users get access to only their data? And will I still have 1 database on server end?
  2. PouchDB on the client side can be in sync with a remote PouchDB. But when an application is build with Javascript how do you make sure that people are not inserting data into PouchDB by 'hacking' the client-side Javascript?
  3. Would the use of a backend be gone in these kinds of setups? And if you want to have an API for 3rd party, you just put for example an Sails.js backend around the CouchDB?
2

There are 2 answers

0
nlawson On BEST ANSWER

PouchDB maintainer here, happy to answer your questions. :)

If I have multiple users with there own authentication, how can I make sure that the users get access to only their data? And will I still have 1 database on server end?

There is a guide in the pouchdb-authentication README. Cloudant and Couchbase also have their own systems for managing users.

PouchDB on the client side can be in sync with a remote PouchDB. But when an application is build with Javascript how do you make sure that people are not inserting data into PouchDB by 'hacking' the client-side Javascript?

You write a validate_doc_update function on the server side. When PouchDB tries to sync to CouchDB, any failed documents will emit a 'denied' event, and those documents will not sync.

As for the local database, you cannot prevent users from writing bad data (they can always open up the console and do whatever they want), but you can use something like pouchdb-validation to re-use your validation function on the client side. Or you can just do it yourself when you put() a document.

Would the use of a backend be gone in these kinds of setups? And if you want to have an API for 3rd party, you just put for example an Sails.js backend around the CouchDB?

Some people write PouchDB apps without any backend (just using pure CouchDB/Cloudant/Couchbase), whereas others like to mix the database with a server architecture of their choice. It's up to you. :)

One interesting solution if you're using Express is to use express-pouchdb, so you can expose a PouchDB Server-like endpoint inside of your existing architecture. For Sails.js, though, you'd have to write your own.

0
ermouth On

PouchDB on the client side can be in sync with a remote PouchDB. But when an application is build with Javascript how do you make sure that people are not inserting data into PouchDB by 'hacking' the client-side Javascript?

To reduce risk you can remove/redefine global variable window.PouchDB. So when your code starts (assuming it runs inside a closure), it can do the following:

function(){
    // your closure
    var PouchDB = window.PouchDB;
    window.PouchDB = null;
    Object.freeze(window);
}

Now PouchDB is visible inside the closure, but is not visible from console.

Last line freezes entire window object, so code can not add any global vars after freeze was executed. You must call Object.freeze(window) after all your libs were received and initialized. Please note this trick can induce a lot of side effects, so test your code carefully.

Object.freeze gurantees user can not copy/paste PouchDB‘s source code to console and run it, but does not guarantee user can not access underlying storage (IDB/WebSQL) directly or using Resources tab of the console.