Search code examples
ibm-mobilefirstcloudantjsonstore

CloudantSync vs. JSONStore


Could someone please explain the key differences between JSONStore and CloudantSync (CDTStore) (and as a bonus PouchDB) on the MobileFirst Platform?

I am having difficulty deciding which one would be better to use.

I see that the documentation here states that JSONStore is better if you need FIPS 140-2 compliance, need to synchronize, or are building a hybrid app. But, it looks like you can do all three of those with CDTStore as well. Also, I've seen PouchDB mentioned in some tutorials. I am trying to understand the key differences between what looks like different methods of doing the same thing. Any insight would be greatly appreciated.


Solution

  • The answer to this question is a bit murky as functionality does overlap a bunch, so sorry in advance. I work on the Cloudant team, so am probably unintentionally biased. I'll try to elaborate on the similarities and differences below (as they stand right now), which will hopefully allow you (and others) to see better which libraries aligns with your app's needs.

    To set the stage, the similarities are broadly:

    • Both store JSON data and expose a NoSQL rather than relational interface.
    • Both use SQLite as an underlying durable datastore.
    • However, neither expose SQLite to the client -- it's an implementation detail. Sync in particular has a somewhat complicated data model in SQLite to support synchronisation metadata.
    • Both are designed to securely store data from remote services locally on a device from remote services.
    • Both offer querying JSON data on device. Both use SQLite's indexing engine under-the-hood.
      • Sync offers a more flexible and powerful system based on Cloudant Query. Sync offers full text search via SQLite's FTS engine.
      • Sync also allows creating and dropping indexes at any point, whereas I believe JSONStore requires defining indexes when creating a collection.

    Sync

    Both Cloudant Sync and JSONStore were designed around the idea of storing data from remote services locally on the device for offline use, or just to make manipulating the data quicker for users.

    We originally designed Cloudant Sync (CDTDatastore on iOS, sync-android on Android) with the purpose of synchronising data with a remote Cloudant or CouchDB server. When used with Cloudant/CouchDB, Cloudant Sync supports automatic, incremental synchronisation as local and remote data changes. Cloudant Sync also has a powerful and flexible model, taken from CouchDB, for resolving changes concurrently made on different servers and devices asynchronously. When used together, the Cloudant Sync + Cloudant/CouchDB are a powerful combination, and uses a reliable and long-in-production sync protocol.

    As you found, JSONStore, on the other hand, is more agnostic as to what its remote database is. This, however, comes at the cost of sync being a fairly manual process -- importantly, though, JSONStore's data model provides capabilities to significantly help with the process.

    The key piece here is that JSONStore can tell you the documents that have changed locally, so you can incrementally upload only changed data. But unless your remote database supports a similar capability of streaming changed data to the client, you have to either send full data snapshots or include the necessary data in your data model to allow for only changed data to be sent (and implement the server-side piece to allow for that to be queried and calculated). JSONStore doesn't support conflict resolution out of the box.

    We provide similar client-accessible hooks for working out locally changed data in Cloudant Sync -- these are used by our own sync engine -- but they are in a rawer and less documented form than JSONStore's, so we generally recommend sticking with the better documented JSONStore. If you want to try out Sync's hooks, the docs for the iOS version are here.

    In summary, if you're working with Cloudant/CouchDB, I suggest Cloudant Sync. If you're working with another datastore, JSONStore may be easier to get started with.

    Security

    Both JSONStore and Cloudant Sync support encrypting data on the client. Both use SQLCipher for encrypting JSON data. Additionally, Cloudant Sync can store "attachments" -- small binary blobs associated with JSON data -- which are also encrypted. JSONStore cannot store binary data.

    When used alongside MobileFirst's client-side SDKs, JSONStore can be used in a FIPS 140-2 solution on MF's supported platforms. MF ships a self-contained OpenSSL binary for this.

    Cloudant Sync uses SQLCipher and CommonCrypto on iOS. SQLCipher can be bought commercially in a FIPS 140-2 version and used with Cloudant Sync. Certain versions of CommonCrypto are FIPS 140-2 validated (see Apple's docs for more). Cloudant Sync for iOS uses exclusively FIPS 140-2 mandated crypto suites where it chooses them for itself.

    On Android, Cloudant Sync again uses SQLCipher, with the same FIPS 140-2 version available for developers to integrate. Android Sync uses javax.crypto to encrypt attachments, however, which is usually not provided in a FIPS 140-2 validated version by vendors. Again, the Sync code uses FIPS 140-2 mandated suites (at the time of writing!).

    What this means is that the situation is more complicated for Cloudant Sync and we've not yet been able to fully confirm our status w.r.t. FIPS 140-2. However, the actual security of the on-device encryption used in JSONStore and Cloudant Sync is identical.

    The summary here is basically that if you don't need FIPS 140-2, go for whichever library is more suitable for your needs or has a function you require. JSONStore is currently recommended for FIPS 140-2 requirements as it's been fully vetted.

    Platform support & Hybrid

    JSONStore supports several platforms. Cloudant Sync is exclusively iOS and Android.

    JSONStore can be used in hybrid applications targeting its supported platforms. Cloudant Sync cannot, yet, without manual wrapping of the library.

    JSONStore's actual implementations are native per platform, so again if you are using iOS or Android the choice is mostly a choice based on other factors.

    PouchDB

    PouchDB can, similarly to Cloudant Sync, sync with Cloudant and CouchDB. As a JS library, it can be easily used in hybrid applications. Unfortunately I'm not that familiar with it, so can't say much more than that with any authority :-/