Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
C

cradle

> 编程语言
Open source

a high-level CouchDB client for Node.js

1.4K stars0 likes3 views
WebsiteGitHub

About

a high-level CouchDB client for Node.js

cradle

A high-level, caching, CouchDB client for Node.js

introduction

Cradle is an asynchronous javascript client for CouchDB. It is somewhat higher-level than most other CouchDB clients, requiring a little less knowledge of CouchDB's REST API. Cradle also has built-in write-through caching, giving you an extra level of speed, and making document updates and deletion easier. Cradle was built from the love of CouchDB and Node.js, and tries to make the most out of this wonderful marriage of technologies.

philosophy

The key concept here is the common ground shared by CouchDB and Node.js, that is, javascript. The other important aspect of this marriage is the asynchronous behaviors of both these technologies. Cradle tries to make use of these symmetries, whenever it can. Cradle's API, although closely knit with CouchDB's, isn't overly so. Whenever the API can be abstracted in a friendlier, simpler way, that's the route it takes. So even though a large part of the Cradle <--> CouchDB mappings are one to one, some Cradle functions, such as save(), can perform more than one operation, depending on how they are used.

synopsis

javascript
  var cradle = require('cradle');
  var db = new(cradle.Connection)().database('starwars');

  db.get('vader', function (err, doc) {
      doc.name; // 'Darth Vader'
      assert.equal(doc.force, 'dark');
  });

  db.save('skywalker', {
      force: 'light',
      name: 'Luke Skywalker'
  }, function (err, res) {
      if (err) {
          // Handle error
      } else {
          // Handle success
      }
  });

installation

bash
  $ npm install cradle

API

Cradle's API builds right on top of Node's asynch API. Every asynch method takes a callback as its last argument. The return value is an event.EventEmitter, so listeners can also be optionally added.

Opening a connection

javascript
  new(cradle.Connection)('http://living-room.couch', 5984, {
      cache: true,
      raw: false,
      forceSave: true,
      request: {
        //Pass through configuration to `request` library for all requests on this connection.
      }
  });

Defaults to 127.0.0.1:5984

Note that you can also use cradle.setup to set a global configuration:

javascript
  cradle.setup({
    host: 'living-room.couch',
    cache: true,
    raw: false,
    forceSave: true
  });

  var c = new(cradle.Connection),
     cc = new(cradle.Connection)('173.45.66.92');

creating a database

javascript
  var db = c.database('starwars');
  db.create(function(err){
    /* do something if there's an error */
  });

checking for database existence

You can check if a database exists with the exists() method.

javascript
  db.exists(function (err, exists) {
    if (err) {
      console.log('error', err);
    } else if (exists) {
      console.log('the force is with you.');
    } else {
      console.log('database does not exists.');
      db.create();
      /* populate design documents */
    }
  });

destroy a database

javascript
  db.destroy(cb);

set revisions limit

Each database has a limit on how many revisions of a document can save.

Default value: 1000

javascript
  db.maxRevisions(4, function(err, res) {
     if (err) {
        console.log('error', err);
     } else {
        console.log('Revisions limit has changed');
     }
  });

get revisions limit

You can also get the current revisions limit

javascript
   db.maxRevisions(function(err, limit) {
      if (err) {
         console.log('error', err);
      } else {
         console.log('Revisions limit is: '+limit);
      }
   });

fetching a document (GET)

javascript
  db.get('vader', function (err, doc) {
      console.log(doc);
  });

If you want to get a specific revision for that document, you can pass it as the 2nd parameter to get().

Cradle is also able to fetch multiple documents if you have a list of ids, just pass an array to get:

javascript
  db.get(['luke', 'vader'], function (err, doc) { ... });

Querying a view

javascript
  db.view('characters/all', function (err, res) {
      res.forEach(function (row) {
          console.log("%s is on the %s side of the force.", row.name, row.force);
      });
  });

You can access the key and value of the response with forEach using two parameters. An optional third parameter will return the id like this example.

javascript
  db.view('characters/all', function (err, res) {
      res.forEach(function (key, row, id) {
          console.log("%s has view key %s.", row.name, key);
      });
  });

To use View Generation Options you can use the view Method with three parameters (viewname, options, callback):

javascript
  db.view('characters/all', {group: true, reduce: true} , function (err, res) {
      res.forEach(function (row) {
          console.log("%s is on the %s side of the force.", row.name, row.force);
      });
  });

Querying a row with a specific key

Lets suppose that you have a design document that you've created:

javascript
  db.save('_design/user', {
    views: {
      byUsername: {
        map: 'function (doc) { if (doc.resource === "User") { emit(doc.username, doc) } }'
      }
    }
  });

In CouchDB you could query this view directly by making an HTTP request to:

  /_design/user/_view/byUsername/?key="luke"

In cradle you can make this same query by using the .view() database function:

javascript
  db.view('user/byUsername', { key: 'luke' }, function (err, doc) {
      console.dir(doc);
  });

Querying a view with an array key

Say you create view for cars that has an array key with make and model

javascript
db.save('_design/cars', {
  views: {
    byMakeAndModel: {
      map: function (doc) {
        if (doc.resource === 'Car' && doc.make && doc.model) {
          var key = [doc.make, doc.model]
          emit(key, doc)
        }
      }
    }
  }
})

If you want all the cars made by Ford with a model name between Rav4 and later (alphabetically sorted). In CouchDB you could query this view directly by making an HTTP request to:

  /_design/cars/_view/byMakeAndModel/?startkey=["Ford"]&endkey=["Ford", "\u9999"]

In cradle you can make this same query by using the .view() database function with startkey and endkey options.

javascript
var util = require('util')
var opts = {
  startkey: ['Ford'],
  endkey: ['Ford', '\u9999']
}
db.view('cars/', opts, function (err, docs) {
  if (err) {
    util.error(err)
    return
  }
  util.debug(docs)
});

In the options object you can also optionally specify whether or not to group and reduce the output. In this example reduce must be false since there is no reduce function defined for the cars/byMakeAndModel. With grouping and reducing the options object would look like:

javascript
var opts = {
  startkey: ['Ford'],
  endkey: ['Ford', '\u9999'],
  group: true,
  reduce: true
}

creating/updating documents

In general, document creation is done with the save() method, while updating is done with merge().

creating with an id (PUT)

javascript
  db.save('vader', {
      name: 'darth', force: 'dark'
  }, function (err, res) {
      // Handle response
  });

creating without an id (POST)

javascript
  db.save({
      force: 'dark', name: 'Darth'
  }, function (err, res) {
      // Handle response
  });

updating an existing document with the revision

javascript
  db.save('luke', '1-94B6F82', {
      force: 'dark', name: 'Luke'
  }, function (err, res) {
      // Handle response
  });

Note that when saving a document this way, CouchDB overwrites the existing document with the new one. If you want to update only certain fields of the document, you have to fetch it first (with get), make your changes, then resave the modified document with the above method.

If you only want to update one or more attributes, and leave the others untouched, you can use the merge() method:

javascript
  db.merge('luke', {jedi: true}, function (err, res) {
      // Luke is now a jedi,
      // but remains on the dark side of the force.
  });

Note that we didn't pass a _rev, this only works because we previously saved a full version of 'luke', and the cache option is enabled.

bulk insertion

If you want to insert more than one document at a time, for performance reasons, you can pass an array to save():

javascript
  db.save([
      { name: 'Yoda' },
      { name: 'Han Solo' },
      { name: 'Leia' }
  ], function (err, res) {
      // Handle response
  });

creating views

Here we create a design document named 'characters', with two views: 'all' and 'darkside'.

javascript
  db.save('_design/characters', {
      all: {
          map: function (doc) {
              if (doc.name) emit(doc.name, doc);
          }
      },
      darkside: {
          map: function (doc) {
              if (doc.name && doc.force == 'dark') {
                  emit(null, doc);
              }
          }
      }
  });

These views can later be queried with db.view('characters/all'), for example.

Here we create a temporary view. WARNING: do not use this in production as it is extremely slow (use it to test views).

javascript
  db.temporaryView({
      map: function (doc) {
        if (doc.color) emit(doc._id, doc);
      }
    }, function (err, res) {
      if (err) console.log(err);
      console.log(res);
  });

Note: If you must use View Generation Options on your temporary view you can use the three parameter version of the temporaryView() Method - similar to the one described above.

creating validation

when saving a design document, cradle guesses you want to create a view, mention views explicitly to work around this.

javascript
  db.save('_design/laws', {
    views: {},
    validate_doc_update:
      function (newDoc, oldDoc, usrCtx) {
        if (! /^(light|dark|neutral)$/.test(newDoc.force))
          throw({forbidden: {error: "invalid value", reason: "force must be dark, light, or neutral"}})
      }
    }
  });

removing documents (DELETE)

To remove a document, you call the remove() method, passing the latest document revision.

javascript
  db.remove('luke', '1-94B6F82', function (err, res) {
      // Handle response
  });

If remove is called without a revision, and the document was recently fetched from the database, it will attempt to use the cached document's revision, providing caching is enabled.

update handlers

Update handlers can be used by calling the update() method, specifying the update handler name, and optionally the document id, the query object and the document body object. Only the update handler name is a required function parameter. Note that CouchDB is able to parse query options only if the URI-encoded length is less than 8197 characters. Use the body parameter for larger objects.

javascript
  db.update('my_designdoc/update_handler_name', 'luke', undefined, { my_param: false }, function (err, res) {
      // Handle the response, specified by the update handler
  });

Connecting with authentication and SSL

javascript
  var connection = new(cradle.Connection)('https://couch.io', 443, {
      auth: { username: 'john', password: 'fha82l' }
  });

or providing a self signed CA certificate

javascript
  var connection = new(cradle.Connection)('https://couch.io', 443, {
      auth: { username: 'john', password: 'fha82l' },
      ca: fs.readFileSync('path_to_self_signed_ca.crt')
  });

or

javascript
  var connection = new(cradle.Connection)('couch.io', 443, {
      secure: true,
      auth: { username: 'john', password: 'fha82l' }
  });

Retry on Connection Issues

For a un

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

JavaScript

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言