CouchDB や Cloudant というデータベースに対してブラウザの JavaScript から(API サーバーなどを使わずに)直接アクセスできるような SDK を作ってみました。
【CouchDB CRUD SDK について】
CouchDB は現在は Apache CouchDB としてオープンソースで開発されている JSON ドキュメント型の NoSQL データベースです。そして Cloudant はその CouchDB を IBM からのサポート付きで IBM Cloud から提供されているものです。要するに CouchDB と Cloudant は実体としては同じものです。ということもあって、以下では両方を指す言葉として "CouchDB" という表現をします(Cloudant を使う場合は "Cloudant" と読み替えてください):
CouchDB には REST API が提供されています。したがって CORS に注意する必要はありますが、ウェブブラウザの JavaScript とこの REST API だけでデータベースやドキュメントの読み書き更新削除(=CRUD、Create Read Update Delete)といった処理そのものは可能です。ただ REST API を実行するのはパスやパラメータの指定で直感的に分かりにくい点があったり、検索方法や CouchDB の特徴ともいえる添付ファイル対応(バイナリデータ対応)の REST API は更に複雑だったりするので、私自身も使うたびに調べる必要に迫られたりと、少々使いにくい点があると感じていました。そういった使い勝手の点も含めて分かりやすい JavaScript での SDK を提供できないかと思いついて作ってみたものです。
作成した CouchDB CRUD SDK 自体は README.md 含めて GitHub で公開しています:
https://github.com/dotnsf/couchdb-crud-sdk
SDK の説明(英語)も GitHub に含まれる SDK.md で紹介していますが、せっかくなのでこのブログでは日本語で使い方を紹介します。
【CouchDB CRUD SDK を使う前提条件】
前提条件というか、当然条件というか、使う対象となる CouchDB(Cloudant) サーバーが必要です。この CouchDB サーバーはインターネットからアクセスできる必要はありませんが、クライアントとなるウェブブラウザを使う PC がインターネットに接続していない場合は後述の CDN が使えないため、SDK の JavaScript ファイルをあらかじめダウンロードするなどしておく必要があります。
またここで用意する CouchDB サーバーはユーザー ID とパスワードで(ベーシック認証で)アクセスできるように構築されている必要があります。API キーを使う方法には未対応です。
自由に使える CouchDB サーバーを持っていない場合に備えて、以下では2つの方法で CouchDB サーバーを用意する方法を紹介します:
(1)docker のコンテナとして用意する
自分の PC に docker をインストールしてある場合であれば以下のコマンドを実行するだけで CouchDB サーバーを localhost:5984 で(ユーザーID=user、パスワード=pass で)動かすことができます:
(2)IBM Cloud のアカウントをお持ちであれば、lite plan という無料枠の範囲内で使える Cloudant サーバーを1アカウントにつき1つだけ使うことができます。ちなみに Cloudant の lite plan で使える容量は 1GB です(その他の条件は下図参照)。バイナリデータなどの膨大な容量のファイルを添付したりしなければ、そこそこ使えるサイズだと思っています:
IBM Cloud 内の Cloudant サーバーを作成した場合のデータベースサーバーのホスト名、ユーザーID、パスワードなどの情報は「サービス資格情報」タブ内の下図の変数として確認することができます:
なお、この方法で Cloudant サーバーを用意する場合は認証方法として "IAM and legacy credential" を選択してください(この "legacy credential" がベーシック認証です。"IAM" のみだとベーシック認証には非対応です):
IBM Cloud のアカウントをこれから作る場合はこちらから登録してください(アカウント作成時にクレジットカードの登録が必要ですが、有料サービスを使わなければ課金対象にはなりません)。
もう1つの前提条件として外部の JavaScript から CouchDB サーバーを利用できるように CORS を正しく設定している必要があります。CouchDB の設定画面内で CORS タブから CORS が enalbed になっていることを確認してください。また CORS 対象のオリジンについては "All domains" を選択するか、"Restrict to specific domains" を選択した上で、この後動かすことになるウェブページのオリジン(URL の "スキーマ://ホスト:ポート" の部分)を指定してください。ここが正しく設定できていないと CORS の制約にかかって JavaScript SDK が正しく実行できなくなります:
【CouchDB CRUD SDK のロードと初期化】
実際にデータの読み書きをする前に SDK ライブラリをロードして初期化する必要があります。その流れを説明します:
まずブラウザ内に以下の1行を加えて、CDN の SDK ライブラリをロードします:
インターネットに接続していない環境で使う場合は上記 URL から couchdb-crud-sdk.js をあらかじめダウンロードして、HTML と同じフォルダにコピーするなどして(その場合は src="./couchdb-crud-sdk.js" と指定)対応してください。
次にユーザー ID、パスワード、CouchDB サーバーのベース URL を指定して CouchDB_CRUD_SDK クラスのインスタンスを初期化します:
これでインスタンス変数 cdb の初期化が完了しました。この変数を使うことで CouchDB サーバー内のデータを読み書きできます。
【CouchDB CRUD SDK を使ったデータベースの作成と削除と一覧取得】
上述の初期化まで完了していればインスタンス変数(cdb)のメソッドでリモートの CouchDB に対する各種処理が実行できます。例えば CouchDB のデータベースに関しては以下のようなメソッドが用意されています:
後述のドキュメント向けメソッドについてもいえることですが、メソッドの実行結果は成功した場合は
といった JSON が返されます。また失敗した場合は
という JSON になります。status の true/false で成功か失敗かを判断し、成功の場合は(必要であれば)result の内容を参照、失敗の場合は error の内容に失敗の理由が記載されているのでそれぞれ参照して処理することができます。 なお、cdb のメソッドは全て非同期(async)関数として定義されている点に注意してください。
【CouchDB CRUD SDK を使ったドキュメントの操作】
次にデータベース内のドキュメントに関しては以下のようなメソッドが用意されています:
createDoc や updateDoc のパラメータで指定されている doc オブジェクトは
といった JSON オブジェクトです(_id の値はいわゆるドキュメント ID です。新規作成時であれば指定されていてもされていなくても構いません、指定がない場合は自動的に付与されます)。
CouchDB の特徴的な機能を使ったメソッドについても紹介しておきます。例えば以下のようなメソッドも用意されています:
上は特定の ID ('doc_id')を持ったドキュメントの全リビジョンを取得するメソッドです。CouchDB はドキュメントの更新履歴が全て(自動的に)リビジョンとして記録されています。つまりドキュメントを新規作成し(リビジョン1)、一度更新して(リビジョン2)、更に更新(リビジョン3)した場合、最新データはリビジョン3ですが、過去のリビジョンも全て記録されていて、取り出すことができます。上の readAllRevisions() メソッドは特定ドキュメントの全リビジョンを一度の取り出すメソッドです。
下は添付ファイルを JSON データの一部として記録する場合のメソッドです。例えば
のような HTLM 要素を使って添付ファイルを読み込もうとした場合であれば、'selector' は "#attachment_file" となります(jQuery などのセレクタだと思ってください)。'filename' は指定されていればそのファイル名で保存されます('filename' 指定がなかった場合は実際のファイル名で保存されます)。なお 'doc_id' が指定されている場合はその ID のドキュメントを更新し、'doc_id' が指定されていない場合は新規にドキュメントを作成します。 この関数を使って(バイナリデータなどの)添付ファイルもブラウザの JavaScript でリモートデータベースに格納/更新できるようになります。またこの添付ファイルの更新記録もリビジョンとして記録されます。
一応ここに挙げたメソッドで一通りの読み書き更新削除まではカバーしていると思いますが、その他全てのメソッドを(最新情報として)参照したい場合はこちらを参照ください(英語です):
https://github.com/dotnsf/couchdb-crud-sdk/blob/main/SDK.md
【CouchDB CRUD SDK のサンプル】
この CouchDB CRUD SDK を比較的汎用的に使ったサンプルアプリケーションを GitHub Pages に用意しておきました。docker コンテナであっても CouchDB/Cloudant 環境があれば試しにアクセスすることができます:
https://dotnsf.github.io/couchdb-crud-sdk/
上記 URL にアクセスすると以下のような画面が表示されます:
上部に3つのテキストフィールドがあり、左からユーザーID、パスワード、CouchDB の URL (docker であれば http://localhost:5984 など)を入力し、最後に Login ボタンをクリックします:
入力した内容が正しい場合は指定された CouchDB にアクセスし、画面左にデータベースの一覧が表示されます。またログインフィールドが画面から消えます(ログインフィールドが残っている場合はログインに失敗しています)。この画面から新しくデータベースを作成(Create DB)することもできます:
データベースを1つ選択すると、そのデータベース内のドキュメント一覧が画面右側に表示されます。この部分からは選択したデータベースの削除(Delete DB)、ドキュメントの新規作成(Create Doc)や、既存ドキュメントの参照(Show Doc)、変更(Edit Doc)、削除(Delete Doc)といったアクションを実行できます:
以下は "Create Doc" ボタンをクリックしてドキュメントを新規作成している画面です:
ドキュメントの内容は JSON 形式であればどのようなフォーマットでも指定可能です。最後に "Save" で保存します:
(わかりにくいかもしれませんが)新たに1つドキュメントが追加されました(赤枠):
このドキュメントの横にある "Show Doc" ボタンをクリックするとドキュメントの内容が表示されます。実際に入力した JSON の内容に加えて、"_id" や "_rev" といったキーとその値が追加されているのがわかります。これらが(自動的に付与された)ドキュメント ID や、そのリビジョンです。同様にして編集や削除も可能です:
このサンプルアプリでできることはこの程度ですが、ブラウザの JavaScript だけでリモートのデータベース内を読み書きできていることがわかると思います。もちろんデータベースを読み書きする REST API があれば(CORS の設定もできていれば)普通にできることではあるんですが、REST API を意識しなくても関数を呼び出すだけでできるようにしたのはまあまあ便利かなと自分でも思っています。API サーバーなしでも動くフロントエンドアプリケーションの SDK という位置付けであり、それが実現できているので現に GitHub Pages でこのサンプルが作れているわけです。
サンプルアプリの内容を見たい場合はこちらを参照ください(index.html, viewer.js, viewer.css の3つのファイルで作られているウェブアプリケーションです):
https://github.com/dotnsf/couchdb-crud-sdk/tree/main/docs
【最後に】
・・・というものを作って公開してみました。ローカルストレージではなくリモートデータベースをブラウザの JavaScript だけで(比較的簡単に)操作できることと、CouchDB の持つリビジョン管理機能や添付ファイル管理まで含めて操作できる点が特徴的なライブラリかな、と思っています。
CouchDB や Cloudant といったデータベースに馴染みのない人もいるかもしれませんが、この記事をきっかけに知ったり興味持ったりしてもらうことがあれば嬉しいです。
【CouchDB CRUD SDK について】
CouchDB は現在は Apache CouchDB としてオープンソースで開発されている JSON ドキュメント型の NoSQL データベースです。そして Cloudant はその CouchDB を IBM からのサポート付きで IBM Cloud から提供されているものです。要するに CouchDB と Cloudant は実体としては同じものです。ということもあって、以下では両方を指す言葉として "CouchDB" という表現をします(Cloudant を使う場合は "Cloudant" と読み替えてください):
CouchDB には REST API が提供されています。したがって CORS に注意する必要はありますが、ウェブブラウザの JavaScript とこの REST API だけでデータベースやドキュメントの読み書き更新削除(=CRUD、Create Read Update Delete)といった処理そのものは可能です。ただ REST API を実行するのはパスやパラメータの指定で直感的に分かりにくい点があったり、検索方法や CouchDB の特徴ともいえる添付ファイル対応(バイナリデータ対応)の REST API は更に複雑だったりするので、私自身も使うたびに調べる必要に迫られたりと、少々使いにくい点があると感じていました。そういった使い勝手の点も含めて分かりやすい JavaScript での SDK を提供できないかと思いついて作ってみたものです。
作成した CouchDB CRUD SDK 自体は README.md 含めて GitHub で公開しています:
https://github.com/dotnsf/couchdb-crud-sdk
SDK の説明(英語)も GitHub に含まれる SDK.md で紹介していますが、せっかくなのでこのブログでは日本語で使い方を紹介します。
【CouchDB CRUD SDK を使う前提条件】
前提条件というか、当然条件というか、使う対象となる CouchDB(Cloudant) サーバーが必要です。この CouchDB サーバーはインターネットからアクセスできる必要はありませんが、クライアントとなるウェブブラウザを使う PC がインターネットに接続していない場合は後述の CDN が使えないため、SDK の JavaScript ファイルをあらかじめダウンロードするなどしておく必要があります。
またここで用意する CouchDB サーバーはユーザー ID とパスワードで(ベーシック認証で)アクセスできるように構築されている必要があります。API キーを使う方法には未対応です。
自由に使える CouchDB サーバーを持っていない場合に備えて、以下では2つの方法で CouchDB サーバーを用意する方法を紹介します:
(1)docker のコンテナとして用意する
自分の PC に docker をインストールしてある場合であれば以下のコマンドを実行するだけで CouchDB サーバーを localhost:5984 で(ユーザーID=user、パスワード=pass で)動かすことができます:
$ docker run -d --name couchdb -p 5984:5984 -e COUCHDB_USER=user -e COUCHDB_PASSWORD=pass
(2)IBM Cloud のアカウントをお持ちであれば、lite plan という無料枠の範囲内で使える Cloudant サーバーを1アカウントにつき1つだけ使うことができます。ちなみに Cloudant の lite plan で使える容量は 1GB です(その他の条件は下図参照)。バイナリデータなどの膨大な容量のファイルを添付したりしなければ、そこそこ使えるサイズだと思っています:
IBM Cloud 内の Cloudant サーバーを作成した場合のデータベースサーバーのホスト名、ユーザーID、パスワードなどの情報は「サービス資格情報」タブ内の下図の変数として確認することができます:
なお、この方法で Cloudant サーバーを用意する場合は認証方法として "IAM and legacy credential" を選択してください(この "legacy credential" がベーシック認証です。"IAM" のみだとベーシック認証には非対応です):
IBM Cloud のアカウントをこれから作る場合はこちらから登録してください(アカウント作成時にクレジットカードの登録が必要ですが、有料サービスを使わなければ課金対象にはなりません)。
もう1つの前提条件として外部の JavaScript から CouchDB サーバーを利用できるように CORS を正しく設定している必要があります。CouchDB の設定画面内で CORS タブから CORS が enalbed になっていることを確認してください。また CORS 対象のオリジンについては "All domains" を選択するか、"Restrict to specific domains" を選択した上で、この後動かすことになるウェブページのオリジン(URL の "スキーマ://ホスト:ポート" の部分)を指定してください。ここが正しく設定できていないと CORS の制約にかかって JavaScript SDK が正しく実行できなくなります:
【CouchDB CRUD SDK のロードと初期化】
実際にデータの読み書きをする前に SDK ライブラリをロードして初期化する必要があります。その流れを説明します:
まずブラウザ内に以下の1行を加えて、CDN の SDK ライブラリをロードします:
<script src="https://dotnsf.github.io/couchdb-crud-sdk/couchdb-crud-sdk.js"></script>
インターネットに接続していない環境で使う場合は上記 URL から couchdb-crud-sdk.js をあらかじめダウンロードして、HTML と同じフォルダにコピーするなどして(その場合は src="./couchdb-crud-sdk.js" と指定)対応してください。
次にユーザー ID、パスワード、CouchDB サーバーのベース URL を指定して CouchDB_CRUD_SDK クラスのインスタンスを初期化します:
var cdb = new CouchDB_CRUD_SDK( username, password, base_url );
これでインスタンス変数 cdb の初期化が完了しました。この変数を使うことで CouchDB サーバー内のデータを読み書きできます。
【CouchDB CRUD SDK を使ったデータベースの作成と削除と一覧取得】
上述の初期化まで完了していればインスタンス変数(cdb)のメソッドでリモートの CouchDB に対する各種処理が実行できます。例えば CouchDB のデータベースに関しては以下のようなメソッドが用意されています:
//. データベース一覧取得 var result0 = await cdb.readAllDbs(); //. データベース新規作成 var result1 = await cdb.createDb( 'newdb' ); //. データベース削除 var result2 = await cdb.deleteDb( 'newdb' );
後述のドキュメント向けメソッドについてもいえることですが、メソッドの実行結果は成功した場合は
{ status: true, result: (実行した結果のオブジェクトや配列) }
といった JSON が返されます。また失敗した場合は
{ status: false, error: (失敗した原因の内容を示すオブジェクトや文字列) }
という JSON になります。status の true/false で成功か失敗かを判断し、成功の場合は(必要であれば)result の内容を参照、失敗の場合は error の内容に失敗の理由が記載されているのでそれぞれ参照して処理することができます。 なお、cdb のメソッドは全て非同期(async)関数として定義されている点に注意してください。
【CouchDB CRUD SDK を使ったドキュメントの操作】
次にデータベース内のドキュメントに関しては以下のようなメソッドが用意されています:
//. データベース内のドキュメント一覧取得 var result3 = await cdb.readAllDocs( 'db' ); //. ドキュメント新規作成 var result4 = await cdb.createDoc( 'db', doc ); //. ドキュメント一件取得 var result5 = await cdb.readDoc( 'db', 'doc_id' ); //. ドキュメント更新 var result6 = await cdb.updateDoc( 'db', 'doc_id', doc ); //. ドキュメント削除 var result7 = await cdb.deleteDoc( 'db', 'doc_id' );
createDoc や updateDoc のパラメータで指定されている doc オブジェクトは
{ _id: 'doc_id', name: "ジュース", price: 120 }
といった JSON オブジェクトです(_id の値はいわゆるドキュメント ID です。新規作成時であれば指定されていてもされていなくても構いません、指定がない場合は自動的に付与されます)。
CouchDB の特徴的な機能を使ったメソッドについても紹介しておきます。例えば以下のようなメソッドも用意されています:
//. 特定ドキュメントの全リビジョン取得 var result8 = await cdb.readAllRevisions( 'db', 'doc_id' ); //. 添付ファイルをドキュメントとして保存する var result9 = await cdb.saveFile( 'db', 'doc_id', 'selector', 'filename' );
上は特定の ID ('doc_id')を持ったドキュメントの全リビジョンを取得するメソッドです。CouchDB はドキュメントの更新履歴が全て(自動的に)リビジョンとして記録されています。つまりドキュメントを新規作成し(リビジョン1)、一度更新して(リビジョン2)、更に更新(リビジョン3)した場合、最新データはリビジョン3ですが、過去のリビジョンも全て記録されていて、取り出すことができます。上の readAllRevisions() メソッドは特定ドキュメントの全リビジョンを一度の取り出すメソッドです。
下は添付ファイルを JSON データの一部として記録する場合のメソッドです。例えば
<input type="file" id="attachment_file"/>
のような HTLM 要素を使って添付ファイルを読み込もうとした場合であれば、'selector' は "#attachment_file" となります(jQuery などのセレクタだと思ってください)。'filename' は指定されていればそのファイル名で保存されます('filename' 指定がなかった場合は実際のファイル名で保存されます)。なお 'doc_id' が指定されている場合はその ID のドキュメントを更新し、'doc_id' が指定されていない場合は新規にドキュメントを作成します。 この関数を使って(バイナリデータなどの)添付ファイルもブラウザの JavaScript でリモートデータベースに格納/更新できるようになります。またこの添付ファイルの更新記録もリビジョンとして記録されます。
一応ここに挙げたメソッドで一通りの読み書き更新削除まではカバーしていると思いますが、その他全てのメソッドを(最新情報として)参照したい場合はこちらを参照ください(英語です):
https://github.com/dotnsf/couchdb-crud-sdk/blob/main/SDK.md
【CouchDB CRUD SDK のサンプル】
この CouchDB CRUD SDK を比較的汎用的に使ったサンプルアプリケーションを GitHub Pages に用意しておきました。docker コンテナであっても CouchDB/Cloudant 環境があれば試しにアクセスすることができます:
https://dotnsf.github.io/couchdb-crud-sdk/
上記 URL にアクセスすると以下のような画面が表示されます:
上部に3つのテキストフィールドがあり、左からユーザーID、パスワード、CouchDB の URL (docker であれば http://localhost:5984 など)を入力し、最後に Login ボタンをクリックします:
入力した内容が正しい場合は指定された CouchDB にアクセスし、画面左にデータベースの一覧が表示されます。またログインフィールドが画面から消えます(ログインフィールドが残っている場合はログインに失敗しています)。この画面から新しくデータベースを作成(Create DB)することもできます:
データベースを1つ選択すると、そのデータベース内のドキュメント一覧が画面右側に表示されます。この部分からは選択したデータベースの削除(Delete DB)、ドキュメントの新規作成(Create Doc)や、既存ドキュメントの参照(Show Doc)、変更(Edit Doc)、削除(Delete Doc)といったアクションを実行できます:
以下は "Create Doc" ボタンをクリックしてドキュメントを新規作成している画面です:
ドキュメントの内容は JSON 形式であればどのようなフォーマットでも指定可能です。最後に "Save" で保存します:
(わかりにくいかもしれませんが)新たに1つドキュメントが追加されました(赤枠):
このドキュメントの横にある "Show Doc" ボタンをクリックするとドキュメントの内容が表示されます。実際に入力した JSON の内容に加えて、"_id" や "_rev" といったキーとその値が追加されているのがわかります。これらが(自動的に付与された)ドキュメント ID や、そのリビジョンです。同様にして編集や削除も可能です:
このサンプルアプリでできることはこの程度ですが、ブラウザの JavaScript だけでリモートのデータベース内を読み書きできていることがわかると思います。もちろんデータベースを読み書きする REST API があれば(CORS の設定もできていれば)普通にできることではあるんですが、REST API を意識しなくても関数を呼び出すだけでできるようにしたのはまあまあ便利かなと自分でも思っています。API サーバーなしでも動くフロントエンドアプリケーションの SDK という位置付けであり、それが実現できているので現に GitHub Pages でこのサンプルが作れているわけです。
サンプルアプリの内容を見たい場合はこちらを参照ください(index.html, viewer.js, viewer.css の3つのファイルで作られているウェブアプリケーションです):
https://github.com/dotnsf/couchdb-crud-sdk/tree/main/docs
【最後に】
・・・というものを作って公開してみました。ローカルストレージではなくリモートデータベースをブラウザの JavaScript だけで(比較的簡単に)操作できることと、CouchDB の持つリビジョン管理機能や添付ファイル管理まで含めて操作できる点が特徴的なライブラリかな、と思っています。
CouchDB や Cloudant といったデータベースに馴染みのない人もいるかもしれませんが、この記事をきっかけに知ったり興味持ったりしてもらうことがあれば嬉しいです。