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?