Introducing CouchDB Nano 7.0.0

The latest release of the official Node.js library for Apache CouchDB

Apache CouchDB Nano is the official Node.js library for use with the Apache CouchDB JSON database. It was originally written by Nuno Job who kindly donated it to the Apache Foundation in 2015.

Nano doesn’t try to do too much as a library — a Nano function call usually maps to single HTTP API call, and it maintains the same parameter names as the HTTP API so with its use, you naturally pick up the underlying CouchDB interface.

Today sees the release of Nano version 7.0.0 which contains the following features:

  • Nano now returns a native JavaScript Promise from (most) function calls that perform an HTTP request.
  • Nano adds a number of ...AsStream() functions that return a streamable object, for operations that tend to return a lot of data or have long-running HTTP requests.
  • Updated TypeScript definitions that accurately model the parameters and return values of all functions.
  • Updated README and source code snippets.
  • Various bug fixes

Callbacks vs Promises

The previous versions of Nano used the callback style to handle asynchronous data transfer. Let’s say you wanted to fetch a document whose _id field was "rita", your Nano code would have looked like this:

Fetch a document — callback style

The callback style involved giving the library a function to be called when the result of an HTTP call was received, The function’s parameter signature followed the “err,data" convention so that code would have to use an if statement or two to determine whether there was an error and to decide how to proceed. The trouble with the callback style was that your code tended to indent with each asynchronous call, getting further to the right with each request:

Fetch three documents in series — callback style

Add to that the complexity of checking the err value after each call, the code became get pretty messy. In Nano 7, you can still use the callback style - the above code will still work - but the recommended approach is to use the Promise that is now returned from each function call. Your code now reads:

Fetch three documents in series — Promises style

The code isn’t any shorter, but it doesn’t indent with every asynchronous action. Successfully retreived data is fed to the subsequent then functions and any errors are corralled by the single catch function at the bottom of the sequence.

If we’re happy to launch multiple HTTP requests at conce, we could simplify the code with:

Fetch three documents in parallel — Promises style

In modern JavaScript, an even more readable way of writing sequential code is to use the await keyword in an async function:

Tidier code with async/await

Now things are starting to get very readable, almost normal in fact.

Just as an aside, it’s much more efficent to fetch the three documents in a single API call, but it’s just a demo:

pssst, you could do this in one API call 🤷‍♀

Streams

In some cases, your code is just a conduit between your app’s user and the data stored in CouchDB. Imagine in your Express app you are exposing an HTTP API call which, when called, fetches data from CouchDB. Your app doesn’t need to hold the data in memory, it can just stream the data from CouchDB to your HTTP client. In Nano 6, all of the function calls returned a streamable object, but in Nano 7 only certain function calls (functions whose name ends with “AsStream”) do:

Streaming data to an HTTP stream directly from the database with Nano 7

The functions that return streams are those that tend to deal with bulk data:

  • nano.db.listAsStream - fetch a list of database names
  • db.attachment.insertAsStream - insert an attachment from a stream
  • db.attachment.getAsStream - retrieve an attachment as a stream
  • db.listAsStream - fetch a list of documents
  • db.findAsStream - query a database using a "Mango" selector
  • db.searchAsStream - perform a Lucene-style query
  • db.viewAsStream - query a MapReduce view
  • db.changesAsStream - fetch a database's changes feed

The above “AsStream” functions return a Request object — every other Nano 7 function returns a Promise. Further details are contained in the Migration Guide.

Getting started with Nano

Download the package from npm:

Install from npm

Import the library into your project:

Import into your project

Configure your CouchDB connection:

Configure your database connection

Create a database and insert some documents:

Insert some documents

Get all the documents:

Fetch the documents

Query documents where a >= 2:

Query the database

Migrating from Nano 6

Nano still supports callbacks so the chances are that your code may not need any changes to work with Nano 7. If you are relying on the streaming capabilities of Nano 6, then you’ll need to make some changes and look for the new ...AsStream functions.

See the Migration Guide and the project’s homepage on npm.

TypeScript support

Nano’s TypeScript definitions are now part of the project and accurately reflect the returned types. To get the best out of TypeScript and CouchDB, you can make your own TypeScript classes that model your app’s data and build on the core Nano definitions:

TypeScript helps to add structure to your code

Keep in touch

Nano is an open source project released under the Apache-2.0 license under the auspices of the Apache Foundation. If you have feedback then feel free to raise and issue or contribute a pull request and become a contributor. We’d love to hear from you!