まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

IBM Cloud から提供されている IDaaS サービスである AppID を使っています。AWS の Cognito や Auth0 のようなユーザーログインの(オンラインサインアップやオンラインパスワード変更、多要素認証なども含めた)機能全般をまとめて提供するサービスです。IBM Cloud のライトアカウントを使って無料枠内で利用することも可能です。単なるログイン機能程度であれば自分で実装してもいいのですが、オンラインサインアップや多要素認証まで考慮すると実装は面倒だし、(実在しないアドレスを使うこともできますが)メールアドレス含めて管理するのは個人情報管理の観点からも、特に試験的/実験的な段階では可能であれば避けたいという運用側の事情もあるため、こういったマネージドサービスを使うメリットは大きいと考えています。事実、自分は公私でよく使っています。
2021082902


で、この AppID を使ってサービス開発をしている中で「ユーザーを無効化したい」という意見をいただきました。実験的な意味合いのあるサービスを作って、ある特定の期間だけはそのサービスを使ってもらい、その期間が完了した後は使わせたくない。でもユーザーを削除してしまうと、何かの際に再度ログインしてもらうこともできなくなったり、再作成しても ID のデータ紐付けが切れてしまってたまったデータとの関連が切れてしまうのでそれは都合が悪い。そのため「いったん無効化してログインできないようにしたい」という、運用上ごもっともな意見でした。

「ユーザーの無効化ね。まあ機能的に用意されてるんだろうな」と楽観視していたのですが、AppID のダッシュボードを調べてみると、どうも「ダッシュボード画面からはユーザーの削除はできるが無効化はできなそう」でした。おっと、これはまずいぞ。。。
2021082903


このユーザー無効化を実現するためのワークアラウンドとして考えたのが「パスワードの強制変更」でした。要は管理者の権限で該当ユーザーのパスワードを強制的に変更することで事実上ログインできなくしてしまう、という方法です。アカウントは残るのでデータやその紐付けも消えることはなく、再度初期パスワードに変更すれば、万が一の時にもう一度ログインしてもらうこともできるようになる、と考えました。

で、じゃあダッシュボードからどのようにパスワードを強制変更するのかというと・・・実はパスワードの強制変更もダッシュボードからできるわけではありません。2021年8月現在、AppID ダッシュボードからはユーザーを削除することはできますが、ユーザーを無効化することも、パスワードを強制変更することもできません。

ただ、AppID SDK にはパスワードを強制変更する API がありました(文字通りの「無効化」は SDK からでもできなさそう・・):
https://www.npmjs.com/package/ibmcloud-appid

2021082901
(↑このページ内の "Set User New Password" 欄参照)


つまり AppID SDK のこの setUserNewPassword 関数を使って自分でプログラムを作れば、ユーザーのパスワードを強制的に変更すること自体は実現できそうでした。それによって実質的な無効化も可能にできるのでは・・と考え、挑戦してみました。以下はその成果の共有です。


【サンプルソースコードの紹介】
AppID のユーザーパスワードを変更するサンプルの Node.js アプリケーションを作って、ソースコードを公開しました:
https://github.com/dotnsf/appid_changepassword

このリポジトリを git clone するかダウンロード&展開してください。

使い方は後述しますが、まずは依存ライブラリをまとめてインストールしておいてください(この手順はソースコードを用意した後に1回だけ行ってください):
$ cd appid_changepassword

$ npm install

このフォルダには4つの JavaScript コードファイルが含まれていますが、それぞれ以下のような役割です(create_users_to_appid.js とか、何気に便利なツールだと自負してます):
ファイル役割
app.jsApp ID の動作確認用ウェブアプリケーション。AppID にログイン&ログアウトするだけ
settings.js動作設定用ファイル
create_users_to_appid.jsCSV ファイルから AppID のユーザーをまとめて作成する CLI アプリ
change_password.jsユーザーIDと新パスワードを指定して、パスワードを強制変更する CLI アプリ


パスワードの変更処理を行うのは change_password.js ですが、app.js や create_users_to_appid.js も含めて、この3つのファイルを動かすためにはあらかじめ settings.js に AppID の接続情報を記載しておく必要があります。以下、一通りの使い方を紹介します。


【サンプルソースコードを動かすための事前設定項目】
このアプリを動かすには、何はともあれ App ID のインスタンスが必要です。IBM Cloud にログインしてダッシュボードから App ID を選択してリソースインスタンスを作成してください。その際に「ライト」プランを選択すると 1000 ユーザー&(一ヶ月)1000 ログインまで無料で利用することが可能です(ログインアカウントがライトアカウントの場合は、ライトプランしか選択できません):
2021082904


作成した AppID インスタンスの「サービス資格情報」から(必要であれば1つ作成した上で)サービス資格情報を選択して、資格情報の内容を確認します:
2021082905


資格情報の中は以下のような JSON フォーマットのテキストになっています:
{
  "apikey": "xxxxx",
  "clientId": "xxxxxxxxxxxxxxxxxxx",
  "secret": "xxxxxxxxxxxxxxxxxxx",
  "tenantId": "xxxxx",
  "profilesUrl": "https://jp-tok.appid.cloud.ibm.com",
    :
    :
}

この中の以下5つの情報が必要です:
・apikey
・secret
・clientId
・tenantId
・region(profilesUrl の "https://" と ".appid.cloud.ibm.com" の間の文字列(上例だと "jp-tok"))

これら5つの値を見つけたら、settings.js 内の該当する変数値として入力し、保存します:
//. IBM App ID
exports.region = '(region の値)';
exports.tenantId = '(tenantId の値)';
exports.apiKey = '(apikey の値)';
exports.secret = '(secret の値)';
exports.clientId = '(clientId の値)';

exports.redirectUri = 'http://localhost:8080/appid/callback';
exports.oauthServerUrl = 'https://' + exports.region + '.appid.cloud.ibm.com/oauth/v4/' + exports.tenantId;

準備の最後に App ID のコールバック URL を登録します。今回のアプリケーションはローカルホストで動かす想定をしていて、その場合はローカルホストで動かす際の URL を事前に AppID に登録しておく必要があります。

IBM Cloud ダッシュボードで作成した App ID を開き、「認証の管理」、「認証設定」を選択して、「Web リダイレクト URL の追加」から "http://localhost:8080/appid/callback" を追加します(ローカルホストで動かすのではなく、公開アドレスで動かす場合はその URL を使って "http(s)://ホスト名/appid/callback" を追加してください):
2021082906


これでアプリケーションを動かす準備ができました。


【サンプルソースコードを使ってユーザーを登録】
このブログエントリの目的は「AppID のユーザーパスワードを変更する方法の紹介」です。そのため実際にログインできるユーザーを使って動作確認する必要がありますが、まずはそのユーザーを登録する必要があり、そのためのツールを紹介します。 既に AppID にユーザーが登録されていて、そのユーザーのパスワードを変更してもいい場合、ここは無視しても構いません。

まずは登録するユーザーを以下のようなフォーマットの CSV ファイルで用意します(newusers.csv 参照):
ユーザー表示名,ユーザーID,ユーザーパスワード
ユーザー表示名,ユーザーID,ユーザーパスワード
    :
    :


1列目のユーザー表示名はログインしたユーザーをアプリケーション内で表示する際に表示される文字列です。AppID の場合、ここはなぜか「8文字以上」という制約があるので、8文字以上の表示名を指定します。

2列目のユーザーIDは「メールアドレス形式のログインID」です。App ID の設定によってはオンラインでパスワードリセットを行ったりすることも可能で、その場合のメール送信先にもなるものです(オンラインパスワードリセットを無効にして運用する場合は実在しないメールアドレスでも構いません)。

3列目のユーザーパスワードは、2列目の ID でログインするユーザーのログイン時に指定するパスワードです。 この3列を一組とした行を必要なユーザーぶんだけ用意します。 なおサンプルで newusers.csv というファイルが含まれていて、その内容は以下のような2行になっています(以下、このファイルを使って紹介しますが、自分でこのファイルに相当する内容のファイルを用意した場合は、そのファイル名に置き換えて読み進めてください):
User0001,user0001@mydomain.com,password1
User0002,user0002@mydomain.com,password2

ではこのファイルを使って AppID にユーザーを登録します。コマンドの最後に CSV ファイル名を指定して、以下のように実行します:
$ node create_users_to_appid newusers.csv

画面に色々出力された後にプロンプトに戻ります。成功していると CSV ファイル内で指定されたユーザーが AppID に登録されているはずです。ダッシュボードから「クラウド・ディレクトリー」、「ユーザー」を選択し、CSV ファイルで指定したユーザーが追加されていることを確認します:
2021082907


検証用のユーザーが AppID に登録できました。まずはこのユーザー ID(と CSV ファイルで指定したパスワード)でログインできるか一度確認しておきます。


【サンプルソースコードを使って登録したユーザーでログイン確認】
では今登録したユーザーが登録したパスワードでログインできるかどうかを確認するため、サンプルのウェブアプリケーションを起動します:
$ node app

App ID のメッセージが数行表示された後に "server starting on 8080 ..." と表示されれば起動完了です。ウェブブラウザを開いて http://localhost:8080/ にアクセスします。すると(ログイン前なので) AppID のログイン画面に転送され、以下のような画面が表示されます:
2021082901


この Email 欄と Password 欄にそれぞれユーザーのメールアドレスとパスワードを入力して "Sign in" ボタンをクリックします。先程 CSV ファイルで作成したユーザーのメールアドレスとパスワード(例えば user0001@mydomain.com と password1)を入力してみます:
2021082902


正しく入力されている状態で "Sign in" ボタンをクリックするとログイン処理が成功し、画面が遷移して以下のような画面に切り替わります。ユーザーの ID、表示名、メールアドレスが表示されています。アドレスはログイン前に指定したものと同じ http://localhost:8080/ ですが、ログインが完了しているのでログイン画面には転送されず、この画面が表示されています。"Logout" ボタンでログアウトできます:
2021082903


ログアウトするとログイン画面に戻ります。試しにもう1人のユーザー情報(ID: user0002@mydomain.com, パスワード: password2)でもログインしてみます:
2021082904


User0002 でもログインできました。CSV ファイルから作成したユーザーで正しくログインできる所まで確認できました:
2021082905


ここまで確認できたらいったんサンプルウェブアプリケーションを終了しておきます。"node app" を実行した画面で Ctrl+C を押してアプリケーションを強制終了させておきます。


【サンプルソースコードを使ってユーザーのパスワードを変更する】
さていよいよ本ブログエントリの本題となる「ユーザーパスワードの強制変更」の箇所です。change_password.js ファイルを使って以下のように実行します:
$ node change_password user0001@mydomain.com Password1

実行時に指定するパラメータは2つあります。1つ目がパスワードを変更したいユーザーのログインID(メールアドレス)、2つ目が変更後のパスワードです(つまり上の例だと user0001@mydomain.com ユーザーのパスワードを Password1 に変更します)。旧パスワードを指定せずに強制的に変更する、という点に注意してください。実行すると色々画面に表示されますが、これも処理が完了するとプロンプトに戻ります。

パスワード変更が正しく行われたかどうかを再度サンプルウェブアプリケーションで確認します:
$ node app

ウェブブラウザで https://localhost:8080/ にアクセスしてログイン画面に移動したら、最初は変更前のパスワード(password1)を指定して user0001@mydomain.com でログインを試みてください。先程はログインできましたが、今はパスワードが変更されているのでログインできないはずです(メールアドレスとパスワードが一致しない、という旨のエラーメッセージが表示されます):
2021082906


改めて変更後のパスワードを指定してログインすると、今度はログインが成功してログイン後の画面が表示されます:
2021082907


これで AppID SDK を使ってログインパスワードを強制的に変更することができることが確認できました。

ちなみにソースコード上でのこのパスワード変更処理箇所はこのようになっています:
var SelfServiceManager = require( 'ibmcloud-appid' ).SelfServiceManager;

  :
  :

selfServiceManager.setUserNewPassword( uuid, password, "en", null, null ).then( function( user ){
  resolve( user );
}).catch( function( err ){
  reject( err );
});

  :
  :


ibmcloud-appid ライブラリを呼び出して SelfServiceManager をインスタンス化し、(省略した部分で)アクセストークンを取得してメールアドレスで指定したユーザーの ID(上記コード上では uuid)を特定します。特定できたら selfServiceManager.setUserNewPassword( uuid, password, "en", null, null ); を実行してパスワードを変更しています(password が新しいパスワード)。3番目のパラメータは言語情報らしいですが現在使われていないらしく、既定値の "en" を指定しています。このあたり、詳しくは SDK の説明もご覧ください。


ともあれ、これで当初の目的である「App ID ユーザーの無効化」に近いオペレーションが実現できそうでした。めでたしめでたし。



Bonsai Elasticsearch はその名前の通り、高速多機能な検索エンジンである Elasticsearch による検索機能をダッシュボード機能も含めてマネージドサービスとして提供するプロバイダーです。日本語の情報が少ないせいか、技術記事含めて情報自体を見ることがあまりありませんでした。偉そうに言ってますが、自分も以下の件で興味を持つまでは存じ上げていませんでした:
2021083002


Bonsai Elasticsearch は Salesforce から提供されている PaaS 環境である herokuサードパーティサービスの1つでもあります。heroku 自体も無料で使える利用枠が提供されていて、また Bonsai Elasticsearch にも無料枠があるため、heroku を経由してサービスを申し込むと「検索エンジンの使えるアプリケーションを無料で開発・運用できる環境」を手に入れることができます。世に多くのクラウド環境はありますが、Elasticsearch が無料で使えるアプリケーション・サーバー環境、という時点でかなり珍しいといえます:
2021083003


一方で、現実的に日本人を対象とするアプリケーションを考えると、検索機能は日本語検索ができなければあまり実用的とはいえません。英語のように単語と単語の間に明確なスペースが入って区切られるわけではない日本語は、テキスト内の単語と単語の区切りを見つける時点でかなりハードルが高く、そこから更に検索インデックスを作る必要があるためです。ここまでの機能がサポートされていないと検索エンジンとしては使いにくいのでした。 例えば自分で自分の(手元の)PC やサーバーに Elasticsearch をインストールした場合であれば、自分で更に日本語形態素解析機能を追加でインストールすればいいのですが、クラウドのマネージドサービスとして提供されている場合、そのような権限をもらえないことも多いため、サービスとして提供されている機能の中に多言語対応(日本語対応)が含まれていないといけない、という高めのハードルが設定されているのでした。

そんな中で見つけたこの Bonsai Elasticsearch 。ネットの日本語情報が少ないということは、日本語が使えないということかな・・・ と勝手に想像していました。 が、Bonsai のドキュメントを調べてみると Bonsai Elasticsearch に始めから導入されているプラグイン一覧の中に日本語形態素解析である "Kuromoji Analyzer" の文字を見つけました。あれ?これはもしかして期待できるやつ?:
https://docs.bonsai.io/article/135-plugins-on-bonsai

2021083001


というわけで、実際に Bonsai Elasticsearch で日本語検索ができるかどうかを調べてみました。結論としてはどうやら使えそう(!!!)だと思ってます。以下はその際の記録です。


【調査に使ったシナリオ】
最初に迷ったのは「何を調べれば日本語検索ができるといえそうか」でした。日本語データを入れて、日本語で検索して、日本語のそれっぽいデータが返ってきたらいいのか?? というと、そうともいえないし・・・

で、今回は Elastic 社の日本語エンジニアリングブログから提供されていた『Elasticsearchで日本語のサジェストの機能を実装する』というエントリで紹介されていた方法が Bonsai Elasticsearch でできるかどうかを調べました。詳細はリンク先を確認していただきたいのですが、大まかな内容としては kuromoji を使う前提で日本語でのサジェスト機能を実装するためのインデックスおよびマッピングを作成し、日本語のデータを入れた上で検索して結果を見る、というものです。ここで紹介されているのは入力ミスまでを考慮した曖昧な検索を行うという内容で、この結果が期待通りになればそれはもう大丈夫でしょ、という判断です。

ちなみに同ページで紹介されている内容自体が日本語サジェストを実現するための考え方なども紹介されていて非常に有用でした。その上で、ここで紹介されていることと同じ内容が Bonsai Elasticsearch に対して行っても同じ結果になるか(Bonsai Elasticsearch で日本語形態素解析が使えれば同じ結果になるはず)、を試してみました:
https://www.elastic.co/jp/blog/implementing-japanese-autocomplete-suggestions-in-elasticsearch


【Bonsai Elasticsearch の準備】
まずは Bonsai Elasticsearch のインスタンスを準備します。自分の場合は heroku 経由でインスタンスを作成したので、その場合の手順を紹介します。

まず heroku で無料アカウントを作成し、クレジットカードを登録しておきます(無料版の Bonsai Elasticsearch を使いますが、そのためには heroku アカウントにクレジットカードの登録が必要です)。改めてブラウザで heroku にログインし、(必要であれば)アプリケーションを1つ作成した上でそのアプリケーションにアドオンとして紐付ける形で Bonsai Elasticsearch を追加します。アプリケーションを選択して、"Overview" タブから "Configure Add-ons" を選択します:
2021083004


アドオンを選択する画面で検索ボックスに "Bonsai" と入力すると "Bonsai Elasticsearch" が見つかるのでこれを選択します:
2021083005


こんな感じの確認画面が表示されたら、無料プランの "Sandbox -  Free" が選択されていることを確認して(これ以外は有料です) "Submit Order Form" ボタンをクリックします:
2021083006


正しく処理されると、アプリケーションのアドオン一覧に "Bonsai Elasticsearch" が追加されます:
2021083007


追加された Bonsai Elasticsearch にアクセスするための接続 URL を確認します。同アプリケーションの "Settings" タブから "Reveal Config Vars" ボタンをクリックします:
2021083008


すると、このアプリケーションの動作時に設定される環境変数の一覧が表示されます。さきほど、Bonsai Elasticsearch を追加した際のオペレーションで "BONSAI_URL" という環境変数が設定されているはずです:
2021083009


ここでコピーした BONSAI_URL の値は、このようなフォーマットのテキストになっているはずです:
https://username:password@xxxxxxxx.us-east-1.bonsaisearch.net:443

この値をこの後のインデックス作成やクエリー実行時に使うことになります。何度も使うことになるのでコピペできるよう、どこかに退避しておきましょう。

ここまで完了すれば Bonsai Elasticsearch の準備は環境です。


【Bonsai Elasticsearch に日本語インデックスと日本語データを作成して検索】
ここまでの準備ができれば Elastic 社の日本語エンジニアリングブログで紹介されていた、この内容を実際に試すことができるようになります:
https://www.elastic.co/jp/blog/implementing-japanese-autocomplete-suggestions-in-elasticsearch

ただ具体的なコマンド入力を考慮すると、このままだと少しわかりにくいため、この内容がもう少し試しやすくなるようなファイルやコマンド集(なんなら実行結果も含まれてますw)を作って公開しました。単に挙動や結果だけを確認したい人はこちらをダウンロードして使ってください:
https://github.com/dotnsf/bonsai_elasticsearch


以下に curl を使った具体的な手順とともに紹介します。日本語エンジニアリングブログによると、最初に kuromoji を使った日本語インデックスを作成する必要があります。上述でダウンロードしたファイルの中に含まれている my_suggest.json が日本語インデックスとマッピングを構成するファイルなので、以下の curl コマンドを実行してこれを Bonsai Elasticsearch に PUT します:
$ curl -XPUT https://username:password@xxxxxxxx.us-east-1.bonsaisearch.net:443/my_suggest -d @my_suggest.json -H 'Content-Type: application/json'

https://username:password@xxxxxxxx.us-east-1.bonsaisearch.net:443 部分は先述の BONSAI_URL の値に置き換えて指定してください。以下同様)

次に検索対象となる日本語データをまとめてバルクアップロードします。データファイルは japanese.json です(厳密には JSON フォーマットではなく、複数の JSON が繋がっているフォーマットです。そのため後述のコマンドで特殊な Content-Type を指定する必要があります)。このファイルを以下の curl コマンドで Bonsai Elasticsearch に POST します:
$ curl -XPOST https://username:password@xxxxxxxx.us-east-1.bonsaisearch.net:443/my_suggest/_bulk --data-binary @japanese.json -H 'Content-Type: application/x-ndjson'

(Content-Type の指定値が 'application/json' ではなく、'application/x-ndjson' となっている点に注意してください)

これで Bonsai Elasticsearch に日本語インデックスと日本語データが格納されました。これらが正しく日本語で検索できるかどうか(このブログの本来の目的でいえば、5種類の曖昧な日本語検索をしても同じ結果になるかどうか)を確認してみます。5種類の検索クエリーを5つのファイル(query1.json, query2.json, ..., query5.json)で用意したので、5回に分けてそれぞれを実行し、その結果を result1.json, result2.json, ..., result5.json に格納します:
$ curl -XGET https://username:password@xxxxxxxx.us-east-1.bonsaisearch.net:443/my_suggest/_search -d @query1.json -H 'Content-Type: application/json' > result1.json

$ curl -XGET https://username:password@xxxxxxxx.us-east-1.bonsaisearch.net:443/my_suggest/_search -d @query2.json -H 'Content-Type: application/json' > result2.json

$ curl -XGET https://username:password@xxxxxxxx.us-east-1.bonsaisearch.net:443/my_suggest/_search -d @query3.json -H 'Content-Type: application/json' > result3.json

$ curl -XGET https://username:password@xxxxxxxx.us-east-1.bonsaisearch.net:443/my_suggest/_search -d @query4.json -H 'Content-Type: application/json' > result4.json

$ curl -XGET https://username:password@xxxxxxxx.us-east-1.bonsaisearch.net:443/my_suggest/_search -d @query5.json -H 'Content-Type: application/json' > result5.json

ちなみにこれらの検索の内容ですが、「日本」という文字を多く含む日本語データがある程度格納されている状況下で、query1.json では「日本」を、query2.json では「にほn」を、query3.json では「にhん」を、query4.json では「にっほん」を、そして query5.json では「日本ん」を検索します。このように入力ミスまで考慮した曖昧な検索をしても同じ検索結果になるようなインデックスとマッピングを作る、という内容でした。実際に result1.json から result5.json まで見ると、検索結果はどれも一致しているはずです。


・・・というわけで、無料の Bonsai Elasticsearch (と導入済みの kuromoji)を使って日本語インデックスで日本語データを期待通りに検索できることがわかりました。こりゃ、いいモン見つけたかも!



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 );
});

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



このページのトップヘ