Hi folks.

I just read this freshly-posted article and it put the finger on a
question I've been asking a lot in my project/team using CouchDB.

https://blog.couchdb.org/2017/04/04/pouchdb-couchdb-an-interview-with-nolan-lawson/

In the third Q&A, Nolan says:

CouchDB’s superpower is sync. Sometimes I even try to explain it to people by saying, *“CouchDB isn’t a database; it’s a sync engine.”*
It’s a way of efficiently transferring data from one place to another,
while intelligently managing conflicts and revisions. It’s similar
to Git. When I make that analogy, the light bulb often goes off.

*“CouchDB isn’t a database; it’s a sync engine.”* rings a bell
because we've been effectively sacrificing the sync-ability of
the projects data store, for reasons I'll detail now.

What we have been doing is adding a layer in front of Couch,
responsible for the following tasks, ordered by importance to us:

1. Reduce facts. In order to avoid conflicts, we are using Couch
   as a store of immutable timestamped "facts". For example,
   fact = {'date: '20170401', 'a': 1, 'b': 2} and
   fact = {'date: '20170402', 'a': null, 'b': 3, 'c': 4}
   are reduced to {'date': '20170402', 'b': 3, 'c': 4}.
   The front layer does this time-ordered reduction, which can't be
   done in Couch2, whose reduce functions have to be commutative.

2.a. Do as much server-side logic as possible, in order to minimize
     what has to be done client-side. (We have multiple clients
     and don't want to ship/repeat logic down there).

2.b. Provide a nice domain-meaningful URL scheme, and
     shield clients from Couch-level view interface changes.

3. Perform document-level access rights.

4. Do things out of reach for Couch, like pseudo-joins.

As we add more valuable features to this layer, the provided client
endpoints get ever less "Couch-like" and lose their Couch <-> Pouch
sync-ability guarantees.

We started with "magically updating" client prototypes humming
on Pouch-backed stores rendered by $whatever_rendering_js_lib and,
a few months later with the new intermediate layer, we're back in
the client to manual HTTP calls and manual binding to filtered
_changes when some magical update is desired (whereas it used to
be the default).

Thoughts?

Reply via email to