本ブログエントリは IBM Cloud アドベントカレンダー 2021 に参加しています。12/4 ぶんのネタです。


IBM Cloud から提供されているマネージド NoSQL データベースである IBM Cloudant をよく使っています。最大の魅力は無料アカウントでも容量 1GB まで使えるストレージで、かつデータが分散管理されているという安全性です。仕様が曖昧な状態からアジャイルに作り始める際は(テーブル定義などを意識する必要がないこともあって)むしろ NoSQL データベースの方が便利だったりもします。

この IBM Cloudant を Node.js プログラムから使う場合のライブラリとして長く @cloudant/cloudant を使ってきましたが、2021/12/31 を以って End of Support を迎えることになり、現在は deprecated なライブラリ、という扱いになっています。2021年8月の今は「まだ使えるけど、もうすぐ使えなくなるよ」って所でしょうか。可能であれば、これから新たに作り始める時には利用を避けたほうが安全だと思います。

で、その後継ライブラリとして公開されているのが @ibm-cloud/cloudant (IBM Cloudant Node.js SDK)です。IBM Cloudant だけでなく、そのベースとなっている Apache CouchDB に対してももちろん使うことができるものです。現在 @cloudant/cloudant ライブラリを使っているアプリケーションはなるべく今年中にこの新しい @ibm-cloud/cloudant に移植することをおすすめします。

・・・と言うのは簡単ですが、実際この @ibm-cloud/cloudant は @cloudant/cloudant と比べてどのくらい似ていて/同じで、移植はどの程度簡単/難しいのでしょう? というわけで、まずは @ibm-cloud/cloudant を使ってみることにしました。


【サンプルソースコード】
以下で紹介するサンプルアプリケーションのソースコードを github で公開しています:
https://github.com/dotnsf/cloudant-node-sdk_sample


【接続方法の決定】
@ibm-cloud/cloudant を使って Cloudant(CouchDB) にアクセスする場合の接続方法には3通りあります:
(1)IAM
(2)COUCHDB_SESSION
(3)BASIC


(1)の IAM は IBM Cloudant を IAM 接続サポート形式で作成した場合に利用できる方法です。公式ドキュメントでも「この方法が使える場合はこの方法で」と紹介されています。

(2)の COUCHDB_SESSION を使った方法でも接続が可能です。

(3)の BASIC はいわゆる「ベーシック認証」です。この3つの中では「この方法しか使えない場合の選択肢」と紹介されています。CouchDB を自分でインストールして使う場合など、この方法で接続する前提のセットアップをしているとこの方法でしか接続できないことになります。もちろん Cloudant でもベーシック認証をサポートした形式で作成している場合は利用可能です。

(1)、(2)、(3)のいずれの方法でアプリケーションとデータベースを接続するかを決めておく必要があります。正確には @ibm-cloud/cloudant は「環境変数を設定して接続する」のですが、どの方法で接続するかによって、設定が必要になる環境変数が変わる点に注意が必要です。


【Node.js から接続する際に必要な環境変数】
@ibm-cloud/cloudant を使って Cloudant/CouchDB に接続する際に設定が必要な環境変数は以下です(横のカッコ付き数字は、上述の(1)、(2)、(3)のどの方法を使った時に必要な環境変数か、を表しています)。また変数名の頭の "CLOUDANT" 部分は別の値でも構いませんが、同じ文字列に統一して設定する必要があります:

変数意味
CLOUDANT_AUTH_TYPE上述の接続方法。"IAM"(1), "COUCHDB_SESSION"(2), "BASIC"(3) のいずれか。デフォルト値は "IAM"
CLOUDANT_URLデータベースの URL((1)、(2)、(3))
CLOUDANT_APIKEYAPI キーの値((1))
CLOUDANT_USERNAMEユーザー名((2)、(3))
CLOUDANT_PASSWORDパスワード((2)、(3))


環境に合わせてこれらの値を用意して実際に接続してみます。


【Node.js から Cloudant に接続】
(1)IAM 接続を行う場合は、上述の表より以下の環境変数を設定します:
process.env['CLOUDANT_AUTH_TYPE'] = 'IAM'; //(デフォルト値なので設定しなくてもよい)
process.env['CLOUDANT_APIKEY'] = 'xxxxx'; //(API Key の値)
process.env['CLOUDANT_URL'] = 'https://xxxxxxx-bluemix.cloudantnosqldb.appdomain.cloud'; //(Cloudant のURL)

そして @ibm-cloud/cloudant ライブラリを読み込んで、以下のコードを実行します:
var { CloudantV1 } = require( '@ibm-cloud/cloudant' );

var client = CloudantV1.newInstance( { serviceName: 'CLOUDANT' } ); 

このコード実行が成功すると、Cloudant に接続したインスタンスが client という変数に格納され、実際のデータの CRUD 処理が可能になります。

なお上記コードの serviceName 値として 'CLOUDANT' を指定していますが、この部分は変更可能です。ただ変更する場合は環境変数として指定した変数名の頭の CLOUDANT 部分をここで指定する値と同じものに変更してください。

(2)COUCHDB_SESSION 接続を行う場合は、上述の表より以下の環境変数を設定します:
process.env['CLOUDANT_AUTH_TYPE'] = 'COUCHDB_SESSION';
process.env['CLOUDANT_USERNAME'] = 'username'; //(ユーザー名の値)
process.env['CLOUDANT_PASSWORD'] = 'password'; //(パスワードの値)
process.env['CLOUDANT_URL'] = 'https://xxxxxxx-bluemix.cloudantnosqldb.appdomain.cloud'; //(Cloudant/CouchDB のURL)

そして @ibm-cloud/cloudant ライブラリを読み込んで、以下のコードを実行します:
var { CloudantV1 } = require( '@ibm-cloud/cloudant' );

var client = CloudantV1.newInstance( { serviceName: 'CLOUDANT' } ); 

(3)BASIC 接続を行う場合は、上述の表より以下の環境変数を設定します:
process.env['CLOUDANT_AUTH_TYPE'] = 'BASIC';
process.env['CLOUDANT_USERNAME'] = 'username'; //(ユーザー名の値)
process.env['CLOUDANT_PASSWORD'] = 'password'; //(パスワードの値)
process.env['CLOUDANT_URL'] = 'http://xxx.xxx.xxx.xxx:5984'; //(Cloudant/CouchDB のURL)

そして @ibm-cloud/cloudant ライブラリを読み込んで、以下のコードを実行します:
var { CloudantV1 } = require( '@ibm-cloud/cloudant' );

var client = CloudantV1.newInstance( { serviceName: 'CLOUDANT', disableSslVerification: true } ); 

なお(CouchDB の場合に多いと想像していますが) SSL 接続が不要の場合は上述のように接続時のパラメータに disableSslVerification: true を追加してください。

参考までに、@cloudant/cloudant の場合は、
var Cloudantlib = require( '@cloudant/cloudant' );
var cloudant = Cloudantlib( { account: "username", password: "password", url: 'https://xxxxxxx-bluemix.cloudantnosqldb.appdomain.cloud' } );
var db = cloudant.db.use( "dbname" );

といった感じでデータベースまでを取得した上で、
db.get( "id", function( err, result ){
  if( err ){
    console.log( err );
  }else{
    console.log( result );
  }
});

のようにして特定データを取得したりしていましたが、この @ibm-cloud/cloudant ではまだデータベースが特定されていない点にご注意ください。


【接続後の CRUD 処理の例】
では接続後の Cloudant クライアントを使って、IBM Cloudant のデータを読み書きしてみましょう。まず対象データベースと id がわかっている特定データを取得してみます。@ibm-cloud/cloudant では以下のような getDocument() メソッドを使うコードとなります:
client.getDocument( { db: "dbname", docId: "id" } ).then( function( result ){
  console.log( result );
}).catch( function( err ){
  console.log( err );
});

client.getDocument() を実行し、そのパラメータ内でデータベースと id を指定する、という方式になります。この点からして @cloudant/cloudant とは異なってますね。

また特定データベースの全データをまとめて取得(@cloudant/cloudant だと db.list() )する場合は以下のような postAllDocs() メソッドを使うコードです:
client.postAllDocs( { db: "dbname", includeDocs: true } ).then( function( result ){
  console.log( result );
}).catch( function( err ){
  console.log( err );
});

データを一件追加する場合は以下のような postDocument() メソッドを使うコードになります:
client.postDocument( { db: "dbname", document: { name: "Kimura" } } ).then( function( result ){
  console.log( result );
}).catch( function( err ){
  console.log( err );
});

以上、あくまでいくつかのメソッドを紹介しただけですが、全般的に行うオペレーションとメソッド名の関係がわかりやすく整頓されているように感じて、比較的慣れやすいのではないかと感じています。