Adapters allow LowlaDB to connect to almost any back-end database or application.
LowlaDB adapters provide a common interface to a wide variety of back-end databases and applications. The interface to adapters has been designed to be as simple as possible to implement on a wide variety of systems.
LowlaDB includes a default implementation of adapters for MongoDB and PostgreSQL that can be embedded within a Node.js application. These implementations are built around a common Node.js API. The easiest way to implement an adapter is to take advantage of this API, but it is also possible to create an adapter directly from the specification if you want to use a platform other than Node.js.
The default LowlaDB adapter is packaged as a Node.js module designed to plug into an Express application. To install it, modify your dependencies in package.json
to include lowladb-node
.
{
"dependencies": {
"body-parser": "~1.8.1",
"cookie-parser": "~1.3.3",
"debug": "~2.0.0",
"express": "~4.9.0",
"jade": "~1.6.0",
"morgan": "~1.3.0",
"serve-favicon": "~2.1.3",
"lowladb-node": "~0.0.5",
}
}
With the dependencies in place, you need to construct a new instance of the module, optionally providing configuration options.
var lowladb = require('lowladb-node');
var app = express();
lowladb.configureRoutes(app, [optional options] );
The available options are described in the API section below.
The LowlaDB client, syncer and adapter all communicate via a simple HTTP-based protocol. This section defines the parts of the protocol that an adapter must implement.
Versions are always generated by adapters.
db.collection
where collection may itself contain embedded periods.The pull stage of synchronization ‘pulls’ modified records from the adapter down to the client. The client begins this process by retrieving the list of modified ids from the syncer. For each id, the client verifies whether it already has the correct version of the document. If not, it adds the id to the list of ids that need to be pulled. Once it has collected sufficient ids, it requests the documents by making a POST request to the adapter at the endpoint
/lowla/pull
with a json body in the form
{
"ids": [
"<id>", "<id>", {...}
]
}
The adapter should generate a response of the form
[
{
"id": "<id>",
"clientNs": "<clientNs>",
"deleted": true|false
},
{
// Document JSON
},
{...}
]
deleted: true
, there is no following document and the next object, if any, will again be metadata.The push stage of synchronization ‘pushes’ modified records from the client directly up to the adapter. The client collects the necessary change data and then makes a POST request to the adapter at the endpoint
/_lowla/push
with a request body of the form
{
"documents": [
{
"_lowla" : {
"id": "<id>",
"version": "<version>",
"deleted": true [optional]
},
"ops" : {
"$set": {
"fieldToModify": "newvalue",
...
},
"$unset": {
"fieldToDelete": "dummyvalue",
...
}
}
},
{...}
]
}
The adapter should generate a response of the form
[
{
"id": "<id>",
"version": "<version>"
"clientNs": "<clientNs>",
"deleted": true|false,
"clientId": "<id that was pushed>"
},
{
// Document JSON
},
{...}
]
deleted: true
, there is no following document and the next object, if any, will again be metadata.clientId
property. If this property is set, the client should delete the original document under the old id and insert the returned document under the new id.deleted: true
in the metadata, but it cannot simply ignore a document as the client will continue to push it until it receives a response.The default adapter has a single API, configureRoutes
that is used to instantiate and configure both the default syncer and adapter.
var lowladb = require('lowladb-node');
var app = express();
var config = lowladb.configureRoutes(app, options);
The following options are supported
datastore
logger
console
.The default adapter itself contains generic functionality for communicating with the syncer and client and defers to an instance of a datastore to handle communication with the specific backend database or application. The API for datastores is small and designed to be straightforward to implement on many platforms. If you are planning on writing a datastore, we recommend starting from the NeDB implementation. You can find further examples, along with examples of how to package a datastore for inclusion in LowlaDB, in the MongoDB and PostgreSQL datastores.