Simply import YACA, and call the factory function. The factory function introspects your CouchDB instance and returns a custom api. This allows you to make intuitive and easy calls to your database, and inspect your database from the commandline. For example, to request all documents from the 'master' view of the '_design/app' design document of your 'primary_db' database you simply make the following call:
api_factory = require('YACA').api_factory;
api_factory(function(error, couchdb_api) {
couchdb_api.primary_db.app.views.master(function(error, response, body) {
console.log(body)
})
})
It is that simple.
YACA was designed for CouchDB databases where the number of databases and the design documents remain relatively stable. As such, the structure of the database is cached, and the api is generated from this cached structure unless update: true
is explicitly passed to the factory. In a future release, YACA will be able to introspect DB changes at will; however, currently, you must create a new couchdb_api instance with the api_factory every time a database is added/removed, or a design document is modified.
YACA is based on Mikeal's request module. Therefore, with a few exceptions listed below, api commands accept an options argument and a callback. They return an error, the original response, and the parsed JSON body. Because it is based on request, you can do fancy things like piping, etc. made possible by Mikeal's module. See https://github.com/mikeal/request for more info.
git clone git://github.com/dgreisen/YACA.git
cd YACA
npm link
The database can be introspected at runtime using the asynchronous api_factory
. When this function is called, the database is introspected, an api is constructed, and a cache of the CouchDB structure is saved. The synchronous api_factory_sync
can use a cache previously generated by the asynchronous api_factory
to synchronously generate an api. The synchronous factory will not introspect the database, only use the cache from a previous introspection. You can optionally call the helper generate_couch_api
from the command line to generate a cache of your couchdb structure.
From within node call:
api_factory = require('YACA').api_factory;
api_factory(factory_options, callback)
factory_options
- an optional hash. See factory options reference for more.callback
- a callback function of the formcallback(error, couchdb_api)
.
From the command line:
generate_couch_api [-f PATH] [-d DB_URL] [-a USERNAME:PASSWORD]
PATH
- the location of the cached database configuration. YACA caches the database structure so it does not have to introspect the database every time it generates an api. If set tofalse
, no cache will be created. Defaults to path/to/YACA/lib/api_cache.json.DB_URL
- the url to your CouchDB instance. It defaults tohttp://127.0.0.1:5984
. If privileges are needed to view design documents or the root instance, provide username and password as:http://username:password@host_name
USERNAME:PASSWORD
- basic auth credentials whereUSERNAME
is an admin username andPASSWORD
is the admin's password, if you wish to be able to access admin-restricted content through the api. The username and password will be stored in the generated cache. See options reference for more.
The command line function is useful for generating a cache that your production code can then access to create an api without ever having to introspect the database. This command simply calls the asynchronous factory.
Once you have a cache, either from the command line or from a previous call to the asynchronous factory:
api_factory_sync = require('YACA').api_factory_sync;
api_factory_sync(file)
file
- the location of the cached database configuration. Defaults to path/to/YACA/lib/api_cache.json.
There are four primary API methods, corresponding to the http methods:
get
put
post
del
To make a call against a database:
couchdb.{{database_name}}.{{http_method}}(options, callback)
or against a particular handler:
couchdb.{{database_name}}
.{{design_doc_name}}
.{{handler_name}}
.{{method}}
.{{http_method}}(options, callback)
See options for what is allowed in options. callback is of the form: callback(error, response, body)
where response
is the unadulterated response from the CouchDB server and body
is a javascript object parsed from the JSON response body.
There are some helper functions described below that have slightly different usage patterns.
Assume we have a CouchDB instance with the following structure:
- CouchDB
- primarydb
- _design/app
- _design/global
- doc1
- secondarydb
- _design/app
- doca
- primarydb
We use the api thus:
couchdb_factory = require('YACA').api_factory;
couchdb_factory( { db_url:'127.0.0.1:5984'
, admin :'administrator:password'
, update:true
}
, handle_api
)
function handle_api(error, couchdb) {
callback = function(error, response, body) {console.log(error, body)}
// create new document
couchdb.primarydb.put({uri:'doc2',json:{field1:'hello'}}, callback)
// view existing document
couchdb.primarydb.get('doc1', callback);
// edit existing document
couchdb.primarydb.put( { uri:'doc2'
, json:{ field1:'goodbye'
, _rev:'34_434c5f645'
}
}
, callback
)
// view all docs from a view
couchdb.secondarydb.app.views.by_date.get(callback)
}
Hopefully this gives you a general idea of how the API works.
When couchdb returns any code greater than 299, the api returns a javascript option parsed from the CouchDB error response with the added field 'statusCode,' with the http StatusCode.
### Factory Options ### The couchdb_factory, takes an optional options hash. If no hash is given, the defaults will be used. The defaults usually work just fine. However it is important to use `update` when the database structure has changed.db_url
- the url to your CouchDB instance. It defaults tohttp://127.0.0.1:5984
. If privileges are needed to view design documents or the root instance, provide username and password as:http(s)://username:password@host_name
admin
- basic auth string,USERNAME:PASSWORD
, whereUSERNAME
is an admin username andPASSWORD
is the admin password, if you wish to be able to access admin-restricted content through the api. The username and password will be stored in plain text in the cache. See [options] reference(#options) for more.file
is the location of the cached database configuration. YACA caches the database structure so it does not have to introspect the database every time it generates an api. If set tofalse
, no cache will be created. Defaults to path/to/YACA/lib/api_cache.json.update
controls introspection. Ifupdate: true
, then the database will be introspected when an api is created even if a cache exists.
You must create a new API whenever you add or remove a database, or you modify a design document.
### Options ### YACA is derived from request, and so it supports most of the options supported by request, and a few moreOptions can be either a string representing the command you wish to execute, or it can be an options object.
The valid keys in the options object are:
uri
||url
- The CouchDB command you wish to execute. the API will prepend the appropriate url for the root/database/design doc/handler method from which you are making the request.body
- entity body for POST and PUT requests. Must be buffer or string.json
- setsbody
but to JSON representation of value and addsContent-type: application/json
header.parse
- defaults totrue
, returnedbody
will be a javascript object parsed from the JSON body.admin
- provide basic auth admin credentials in the request to the database. Only provided if admin credentials were provided to couchdb_factory.query
- hash object of query parameters. api uses JSON.stringify on any non-string hash values. Then uses querystring.stringify on the entire hash.auth
- not yet supported. provide the given basic auth credentials. value must be a string:username:password
.onResponse
- not yet supported.
All of the following API calls are passed an options argument and a callback. The callback is then called with three arguments: an error, the CouchDB http response, and a javascript object parsed from the CouchDB response
- couchdb(options, callback) - shortcut for .get
- couchdb.get(options, callback)
- couchdb.post(options, callback)
- couchdb.put(options, callback)
- couchdb.del(options, callback)
- couchdb.{{db}}(options, callback) - shortcut for .get
- couchdb.{{db}}.get(options, callback)
- couchdb.{{db}}.post(options, callback)
- couchdb.{{db}}.put(options, callback)
- couchdb.{{db}}.del(options, callback)
Where {{db}} is the name of the database. if your database name is a protected word, the YACA database factory will notify you, and {{db}} will be your database name prepended with '__' (two underscores).
- couchdb.{{db}}.{{ddoc}}(options, callback) - shortcut for .get
- couchdb.{{db}}.{{ddoc}}.get(options, callback)
- couchdb.{{db}}.{{ddoc}}.post(options, callback)
- couchdb.{{db}}.{{ddoc}}.put(options, callback)
- couchdb.{{db}}.{{ddoc}}.del(options, callback)
Where {{db}} is as described above, and {{ddoc}} is the _id of your design doc stripped of the '_design/'.
- couchdb.{{db}}.{{ddoc}}.views.{{method}}.get(options, callback)
- couchdb.{{db}}.{{ddoc}}.views.{{method}}.post(options, callback)
- couchdb.{{db}}.{{ddoc}}.shows.{{method}}(options, callback) - shortcut for .get
- couchdb.{{db}}.{{ddoc}}.shows.{{method}}.get(options, callback)
- couchdb.{{db}}.{{ddoc}}.shows.{{method}}.post(options, callback)
- couchdb.{{db}}.{{ddoc}}.lists.{{method}}.get(options, callback) - shortcut for .get
- couchdb.{{db}}.{{ddoc}}.lists.{{method}}.post(options, callback)
- couchdb.{{db}}.{{ddoc}}.updates.{{method}}(options, callback) - shortcut for .put
- couchdb.{{db}}.{{ddoc}}.updates.{{method}}.put(options, callback)
- couchdb.{{db}}.{{ddoc}}.updates.{{method}}.post(options, callback)
- couchdb.{{db}}.{{ddoc}}.rewrites.{{method}}(options, callback) - shortcut for .get
- couchdb.{{db}}.{{ddoc}}.rewrites.{{method}}.get(options, callback)
- couchdb.{{db}}.{{ddoc}}.rewrites.{{method}}.pust(options, callback)
- couchdb.{{db}}.{{ddoc}}.rewrites.{{method}}.post(options, callback)
- couchdb.{{db}}.{{ddoc}}.rewrites.{{method}}.del(options, callback)
couchdb._uuids(3, callback(e, b) {console.log(b)})
// response: [{{uuid1}}, {{uuid2}}, {{uuid3}}]
couchdb.get( {uri:'_uuid',query:{count:'3'}}
, callback(e, r, b) {console.log(b)})
// response: {uuids: [{{uuid1}}, {{uuid2}}, {{uuid3}}]}
As you can see, the helper functions simply reduce the verbosity. If you are already familiar with the couchdb apis, it might be easier to use the standard API rather than having to refer to the helper api.
- couchdb._uuids([count], callback(error, uuids))
count
- number of uuids to return - defaults to 1uuids
- array of uuid strings returned by CouchDB
Returns an array of count
uuids retrieved from a call to _uuids.
- _new_doc(json, admin=false, callback(error, response, body))
json
- the document body as a javascript object.admin
- whether to provide admin credentials for the operation
Requests a uuid from the CouchDB server, puts the document described by json
at that uuid. Returns the server response.
- _delete(uuid, admin=false, callback(error, response, body))
uuid
- the uuid of the document to deleteadmin
- whether to provide admin credentials for the operation
Unsafe Deletion! Deletes the object referenced by uuid
without regard to version numbers.
- couchdb.{{db}}.{{ddoc}}.views.{{method}}(query, callback)
query
- query parameters to pass to the view
Returns standard (error, response, body) to the callback.