IBM Cloudant Node.js SDK Version 0.0.11
Node.js client library to interact with the
IBM Cloudant APIs.
Disclaimer: this SDK is being released initially as a pre-release version.
Changes might occur which impact applications that use this SDK.
Table of Contents
Overview
The IBM Cloudant Node.js SDK allows developers to programmatically
interact with IBM Cloudant
with the help of the @ibm-cloud/cloudant
package.
Features
The purpose of this Node.js SDK is to wrap most of the HTTP request APIs
provided by Cloudant and supply other functions to ease the usage of Cloudant.
Moreover, it has limited support for CouchDB as well.
This SDK should make life easier for programmers to do what’s really important
for them: develop.
Reasons why you should consider using Cloudant Node.js SDK in your
project:
- Supported by IBM Cloudant.
- Includes all the most popular and latest supported endpoints for
applications.
- Handles the authentication.
- Familiar user experience of IBM Cloud SDKs.
Promise
based design with asynchronous HTTP requests.- Use either as native JavaScript or take advantage of TypeScript models.
- Transparently compresses request and response bodies.
Prerequisites
- You need an IBM Cloud account.
- An IAM API key to allow the SDK to access your account.
Create one here.
- Node.js 10, 12, 14: This SDK is tested with Node.js versions 10, 12, and 14.
It may work on other versions but those are not officially supported.
Installation
npm install @ibm-cloud/cloudant
Authentication
This library requires some of your
Cloudant service credentials to authenticate with your
account.
IAM
, COUCHDB_SESSION
, BASIC
or NOAUTH
authentication type.
- IAM authentication is highly recommended when your
back-end database server is Cloudant. This
authentication type requires a server-generated
apikey
instead of a
user-given password. - Session cookie (
COUCHDB_SESSION
) authentication
is recommended for Apache CouchDB or for
Cloudant when IAM is unavailable. It exchanges username
and password credentials for an AuthSession
cookie from the /_session
endpoint. - Basic (or legacy) authentication is a fallback
for both Cloudant and Apache CouchDB
back-end database servers. This authentication type requires the good old
username
and password
credentials. - Noauth authentication does not need any credentials. Note that this
authentication type will only work for queries against a database with read
access for everyone.
- The service
url
.
There are several ways to set these properties:
- As environment variables
- The programmatic approach
- With an external credentials file
Authenticate with environment variables
IAM authentication
For Cloudant IAM authentication set the following environmental variables by
replacing <url>
and <apikey>
with your proper
service credentials. There is no need to set
CLOUDANT_AUTH_TYPE
to IAM
because it is the default.
CLOUDANT_URL=<url>
CLOUDANT_APIKEY=<apikey>
Session cookie authentication
For COUCHDB_SESSION
authentication set the following environmental variables
by replacing <url>
, <username>
and <password>
with your proper
service credentials.
CLOUDANT_AUTH_TYPE=COUCHDB_SESSION
CLOUDANT_URL=<url>
CLOUDANT_USERNAME=<username>
CLOUDANT_PASSWORD=<password>
Basic authentication
For Basic authentication set the following environmental variables by
replacing <url>
, <username>
and <password>
with your proper
service credentials.
CLOUDANT_AUTH_TYPE=BASIC
CLOUDANT_URL=<url>
CLOUDANT_USERNAME=<username>
CLOUDANT_PASSWORD=<password>
Note: We recommend using IAM for Cloudant and
Session for CouchDB authentication.
Authenticate with external configuration
To use an external configuration file, the
Cloudant API docs,
or the
general SDK usage information
will guide you.
Authenticate programmatically
To learn more about how to use programmatic authentication, see the related
documentation in the
Cloudant API docs
or in the
Node.js SDK Core document about authentication.
Code examples
The code examples below will follow the
authentication with environment variables.
1. Retrieve information from an existing database
This example code gathers some information about an existing database hosted on
the https://examples.cloudant.com/ service url
. To do this, you need to
extend your environment variables with the service url and authentication
type to use NOAUTH
authentication while reaching the animaldb
database.
This step is necessary for the SDK to distinguish the EXAMPLES
custom service
name from the default service name which is CLOUDANT
.
EXAMPLES_URL=https://examples.cloudant.com
EXAMPLES_AUTH_TYPE=NOAUTH
Once the environment variables are set, you can try out the code examples.
TypeScript:
const client =
CloudantV1.newInstance({serviceName:"EXAMPLES"});
client.getServerInformation()
.then(serverInformation => {
const version = serverInformation.result.version;
console.log(`Server version ${version}`);
});
const dbName = "animaldb";
client.getDatabaseInformation({db: dbName})
.then(dbInfo => {
const documentCount = dbInfo.result.doc_count;
const dbNameResult = dbInfo.result.db_name;
console.log(`Document count in "${dbNameResult}" database is ` +
documentCount + ".");
});
const getDocParams:
CloudantV1.GetDocumentParams = {db: dbName, docId: "zebra"};
client.getDocument(getDocParams)
.then(documentAboutZebra => {
const result: CloudantV1.Document = documentAboutZebra.result;
console.log("Document retrieved from database:\n" +
JSON.stringify(result, null, 2));
});
JavaScript:
const getInfoFromExistingDatabase = async () => {
const client = CloudantV1.newInstance({ serviceName: 'EXAMPLES' });
const version = (await client.getServerInformation()).result.version;
console.log(`Server version ${version}`);
const dbName = 'animaldb';
const dbInfo = await client.getDatabaseInformation({ db: dbName });
const documentCount = dbInfo.result.doc_count;
const dbNameResult = dbInfo.result.db_name;
console.log(`Document count in "${dbNameResult}" database is ` + documentCount + '.');
const getDocParams = { db: dbName, docId: 'zebra' };
const documentAboutZebra = await client.getDocument(getDocParams);
const result = documentAboutZebra.result;
console.log('Document retrieved from database:\n' + JSON.stringify(result, null, 2));
};
if (require.main === module) {
getInfoFromExistingDatabase();
}
The result of the code is similar to the following output.
The order of the output lines may change due to the asynchronicity.
Server version 2.1.1
Document count in "animaldb" database is 11.
Document retrieved from database:
{
"_id": "zebra",
"_rev": "3-750dac460a6cc41e6999f8943b8e603e",
"wiki_page": "http://en.wikipedia.org/wiki/Plains_zebra",
"min_length": 2,
"max_length": 2.5,
"min_weight": 175,
"max_weight": 387,
"class": "mammal",
"diet": "herbivore"
}
2. Create your own database and add a document
Now comes the exciting part of creating your own orders
database and adding
a document about Bob Smith with your own IAM or
Basic service credentials.
TypeScript:
interface OrderDocument extends CloudantV1.Document {
name?: string;
joined?: string;
_id: string;
_rev?: string;
}
const client = CloudantV1.newInstance({});
const exampleDbName = "orders";
const createDb = client.putDatabase({db: exampleDbName})
.then(putDatabaseResult => {
if (putDatabaseResult.result.ok) {
console.log(`"${exampleDbName}" database created."`);
}
})
.catch(err => {
if (err.code === 412){
console.log("Cannot create \"" + exampleDbName +
"\" database, it already exists.");
}
});
const exampleDocId = "example";
const exampleDocument: OrderDocument = {_id: exampleDocId};
exampleDocument.name = "Bob Smith";
exampleDocument.joined = "2019-01-24T10:42:99.000Z";
createDb.then(() => {
client.getDocument({db: exampleDbName, docId: exampleDocId})
.then(documentInfo => {
exampleDocument._rev = documentInfo.result._rev;
console.log("The document revision for" + exampleDocId +
"is set to " + exampleDocument._rev);
})
.catch(err => {
if (err.code === 404) {
}
})
.finally(() => {
client.postDocument({
db: exampleDbName,
document: exampleDocument
}
).then(createDocumentResponse => {
exampleDocument._rev = createDocumentResponse.result.rev;
console.log("You have created the document:\n" +
JSON.stringify(exampleDocument, null, 2));
});
});
});
JavaScript:
const createDbAndDoc = async () => {
const client = CloudantV1.newInstance({});
const exampleDbName = 'orders';
try {
const putDatabaseResult = (
await client.putDatabase({
db: exampleDbName,
})
).result;
if (putDatabaseResult.ok) {
console.log(`"${exampleDbName}" database created.`);
}
} catch (err) {
if (err.code === 412) {
console.log('Cannot create "' + exampleDbName + '" database, it already exists.');
}
}
const exampleDocId = 'example';
const exampleDocument = { _id: exampleDocId };
exampleDocument['name'] = 'Bob Smith';
exampleDocument.joined = '2019-01-24T10:42:99.000Z';
try {
exampleDocument._rev = (
await client.getDocument({
db: exampleDbName,
docId: exampleDocId,
})
).result._rev;
console.log(
'The document revision for "' + exampleDocId + '" is set to ' + exampleDocument._rev
);
} catch (err) {
if (err.code === 404) {
}
} finally {
const createDocumentResponse = await client.postDocument({
db: exampleDbName,
document: exampleDocument,
});
exampleDocument._rev = createDocumentResponse.result.rev;
console.log('You have created the document:\n' + JSON.stringify(exampleDocument, null, 2));
}
};
if (require.main === module) {
createDbAndDoc();
}
The result of the code is similar to the following output.
The order of the output lines may change due to the asynchronicity.
"orders" database created.
You have created the document:
{
"_id": "example",
"name": "Bob Smith",
"joined": "2019-01-24T10:42:99.000Z",
"_rev": "1-1b403633540686aa32d013fda9041a5d"
}
3. Update your previously created document
Note: this example code assumes that you have created both the orders
database and the example
document by
running this previous example code
successfully, otherwise you get the Cannot update document because either "orders" database or "example" document was not found.
message.
TypeScript:
interface OrderDocument extends CloudantV1.Document {
address?: string;
joined?: string;
_id?: string;
_rev?: string;
}
const client = CloudantV1.newInstance({});
const exampleDbName = "orders";
const getDocParams: CloudantV1.GetDocumentParams =
{docId: "example", db: exampleDbName};
client.getDocument(getDocParams)
.then(docResult => {
const document: OrderDocument = docResult.result;
document.address = "19 Front Street, Darlington, DL5 1TY";
delete document.joined;
client.postDocument({db: exampleDbName, document})
.then(res => {
document._rev = res.result.rev;
console.log("You have updated the document:\n" +
JSON.stringify(document, null, 2));
});
})
.catch(err => {
if (err.code === 404) {
console.log(
"Cannot update document because either \"" +
exampleDbName + "\" database or the \"example\" " +
"document was not found."
);
}
});
JavaScript:
const updateDoc = async () => {
const client = CloudantV1.newInstance({});
const exampleDbName = 'orders';
try {
const document = (
await client.getDocument({
docId: 'example',
db: exampleDbName,
})
).result;
document.address = '19 Front Street, Darlington, DL5 1TY';
delete document['joined'];
document._rev = (
await client.postDocument({
db: exampleDbName,
document: document,
})
).result.rev;
console.log('You have updated the document:\n' + JSON.stringify(document, null, 2));
} catch (err) {
if (err.code === 404) {
console.log(
'Cannot update document because either "' +
exampleDbName +
'" database or the "example" ' +
'document was not found.'
);
}
}
};
if (require.main === module) {
updateDoc();
}
The result of the code is similar to the following output.
You have updated the document:
{
"_id": "example",
"_rev": "2-70476cf75eb02f55c6c4061aa6941ec8",
"name": "Bob Smith",
"address": "19 Front Street, Darlington, DL5 1TY"
}
4. Delete your previously created document
Note: this example code assumes that you have created both the orders
database and the example
document by
running this previous example code
successfully, otherwise you get the Cannot delete document because either "orders" database or "example" document was not found.
message.
TypeScript:
interface OrderDocument extends CloudantV1.Document {
name?: string;
address?: string;
joined?: string;
_id?: string;
_rev?: string;
}
const client = CloudantV1.newInstance({});
const exampleDbName = "orders";
const exampleDocId = "example";
const getDocParams: CloudantV1.GetDocumentParams =
{docId: exampleDocId, db: exampleDbName};
client.getDocument(getDocParams)
.then(docResult => {
const document: OrderDocument = docResult.result;
client.deleteDocument({
db: exampleDbName,
docId: document._id,
rev: document._rev}).then(() => {
console.log("You have deleted the document.");
});
})
.catch(err => {
if (err.code === 404) {
console.log(
"Cannot delete document because either \"" +
exampleDbName + "\" database or the \"example\" " +
"document was not found."
);
}
});
JavaScript:
const deleteDoc = async () => {
const client = CloudantV1.newInstance({});
const exampleDbName = 'orders';
const exampleDocId = 'example';
try {
const document = (
await client.getDocument({
docId: exampleDocId,
db: exampleDbName,
})
).result;
await client.deleteDocument({
db: exampleDbName,
docId: document._id,
rev: document._rev,
});
console.log('You have deleted the document.');
} catch (err) {
if (err.code === 404) {
console.log(
'Cannot delete document because either "' +
exampleDbName +
'" database or the "example" ' +
'document was not found.'
);
}
}
};
if (require.main === module) {
deleteDoc();
}
The result of the code is the following output.
You have deleted the document.
Error handling
For sample code on handling errors, please see
Cloudant API docs.
Using the SDK
For general SDK usage information, please see
this link.
Questions
If you are having difficulties using this SDK or have a question about
the IBM Cloud services, please ask a question on
Stack Overflow.
Issues
If you encounter an issue with the SDK, you are welcome to submit
a bug report.
Before that, please search for similar issues. It's possible someone has
already encountered this issue.
Further resources
Open source @ IBM
Find more open source projects on the IBM Github Page.
Contributing
See CONTRIBUTING.
License
This SDK is released under the Apache 2.0 license.
The license's full text can be found in LICENSE.