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

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

タグ:ibm

IBM Cloud からはオープンソースのブロックチェーン基盤である Hyperledger Fabric をベースとしたマネージドなブロックチェーン環境が提供されています。この 3/21 からは Starter Membership Plan という、名前の通りに小規模向けの比較的安価なプランも提供されるようになりました。2018/03/25 時点ではベータ版で、通常プランと比較していくつかの制約はありますが、無料で利用できます。早速使ってみました。今回のブログエントリではサービスを選択して利用可能にする所までの手順を紹介します。あくまでベータ版であり、今後の仕様変更等により以下の内容は正しい情報ではなくなる可能性もあります。以下の内容は 2018/03/25 時点での情報であることをご了承ください。


また、以下で紹介する IBM Cloud から提供されているブロックチェーンサービスは、IBM Cloud の無料アカウント版であるライトプランからは利用できません(2018/03/25 時点)。以下で紹介する Starter Membership Plan のベータ版は無料ですが、ライトプランのアカウントからはサービスを選択することはできません。実際に試す場合はクレジットカードを登録するなどしてスタンダードプラン等に移行してからご利用ください。


IBM Cloud にログインしてからカタログを表示し、ブロックチェーンカテゴリーを選択すると、対象サービスが "Blockchain" だけに絞り込まれます。これを選択します:
2018032401


次の画面でリージョンやプランを選択します。今回紹介する Starter Membership Plan は 2018/03/25 時点では米国南部リージョンからのみ提供されています。そのためロケーションを選択する箇所で「米国南部」を選ぶようにしてください:
2018032402


画面を下にスクロールすると利用プランの選択画面になります。上記で米国南部リージョンを選択しているとここが選択肢になっていて、Starter Membership Plan か Enterprise Membership Plan が選べるようになっているはずです(米国南部以外のリージョンだと有料の Enterprise Membership Plan のみ)。ここで Starter Membership Plan を選択して「作成」ボタンをクリックします:
2018032403


なお上図にも書かれているように Starter Membership Plan の場合、以下のような制約事項があります。シングルピア環境なので多数決をとるようなスマートコントラクトを実装することはできませんが、アプリケーションとしての実装はほぼ変わらないものを動かすことが可能になります:
・組織は2つまで
・各組織ごとに1ピアまで


サービスが作成されるとダッシュボード内のサービス一覧内にブロックチェーンサービスが表示されるようになります:
2018032404


作成したブロックチェーンサービスを選択するとブロックチェーンサービスの概要が表示されます(この辺りはプランによる違いはないと思われます)。ここから実際にブロックチェーンを操作したり管理するためのダッシュボードを開いてみます。「管理」タブの「起動」ボタンをクリックします:
2018032405


すると別ウィンドウでブロックチェーン環境のダッシュボードが表示されます。下画面ではトランザクションの順番を決定するオーダラーや、CA(認証局)、そしてピアとなるサーバー環境が動いている様子が確認できます:
2018032406


これまで自分で Hyperledger Fabric 環境を構築しようとすると、サーバー環境を用意した上でこれらの各種サーバーを自分で作って運用する必要がありました。そこまでの構築作業とサーバーとしての運用部分を IBM Cloud に任せて、実際のアプリケーション開発・実行やユーザー登録といった実務に集中できる環境として提供されていることが分かります。ブロックチェーンに興味のある方は是非今のうちに色々使ってみてはいかがでしょうか?

なお、今回は IBM Cloud 上にサービスを作る作業までを紹介しました。次回以降でこのサービスにビジネスネットワークアプリケーションをデプロイして動かせるようになるまでの手順を紹介する予定です。



オープンソースのブロックチェーン環境である Hyperledger Fabric と、その開発ツールである Composer の環境を手元のマシンに導入する手順を紹介します。基本手順は以前に IDCF テックブログに寄稿させていただいた内容と同じですが、各モジュールのバージョンや導入直後のカード作成の部分が異なっているので、補足する形で紹介します。

前提条件

まず、以下の説明では前提プラットフォームとして Ubuntu 16.04 を使います。ここに Docker, Docker-Compose, Node.js V6.x を導入してから Hyperledger Fabric をインストールしていくのですが、この3つ(Docker, Docker-Compose, Node.js V6.x)が導入されていれば macOS でも可能です(macOS でのこれら3つの導入手順は省略させてください、普通にググれば見つかると思うので・・・)。以下はこれら3つが導入されている前提で、それ以降の手順を紹介します(Ubuntu でも macOS でも手順は同じです)。

というわけで、この時点では以下の3つのモジュールが導入されているものとします(バージョンは 2018/02 時点で手順に沿って実施した場合に入るバージョンでした):
 - Docker 17.12.0-ce
 - Docker-Compose 1.12.0
 - Node.js v6.12.3

ここまでの導入手順については、こちらを参照ください:
Hyperledger Fabric でブロックチェーン環境を構築


Hyperledger Composer コマンドラインインターフェース

前提環境を整える時に導入されている npm コマンドを使って、Hyperledger Composer のコマンドラインインターフェース(composer-cli)をインストールします:
$ sudo npm install -g composer-cli

(↓2018/03/27 追記)
以下の PeerAdmin@hlfv1 カードを作成する際の仕様が変わったため、ここでは composer-cli のバージョン v0.16.3 を指定してインストールする必要があります。したがって以下のコマンドを実行してください:
$ sudo npm install -g composer-cli@0.16.3
(↑2018/03/27 追記)


導入に成功すると composer コマンドが使えるようになります。2018/02 時点でのバージョンは 0.16.3 でした:
$ composer
v0.16.3

Hyperledger Fabric 開発環境サポートツール

「サポートツール」と呼ばれるファイル群を使って、開発環境として使える Hyperledger Fabric を導入します。一般的にブロックチェーンでは「分散台帳」と呼ばれる方式でデータを複数のノードに分散して共有する仕組みを取りますが、開発環境では1ノードのみ使います。

まず、この時点で docker サービスが有効になっている必要があります。docker サービスが停止している場合は、このタイミングで起動しておきます:
$ sudo service docker start

改めてサポートツールを使って Hyperledger Fabric 環境を導入します。以下の例では ~/fabric というフォルダを作って、その下にサポートツールを導入しています:
$ cd
$ mkdir fabric  (ホームディレクトリ配下の ~/fabric/ にサポートツールを導入する場合)
$ cd fabric
$ curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/master/packages/fabric-dev-servers/fabric-dev-servers.zip
$ unzip fabric-dev-servers.zip

「サポートツールの導入」といっても実質「zip ファイルの展開」です。展開ファイルを確認します:
$ ls
_loader.sh                downloadFabric.sh       startFabric.sh
composer-logs             fabric-dev-servers.zip  stopFabric.sh
createComposerProfile.sh  fabric-scripts          teardownAllDocker.sh
createPeerAdminCard.sh    package.json            teardownFabric.sh

2018/02 版では以前に紹介した時よりもファイルが増えています。これは Hyperledger Composer の仕様変更に伴うもので、以前にはなかった createPeerAdminCard.sh などは環境準備後に使うことになります。

では展開したサポートツールを使って Hyperledger Fabric 環境を構築します。といってもコマンドはこれひとつです:
$ ./downloadFabric.sh

このコマンドの中で必要とされる docker イメージのダウンロード等が行われ、Hyperledger Fabric 環境がローカルマシン内に構築されます。

コマンドが終了したら、いったんこの時点で docker コンテナのプロセスを確認します。他の用途で docker を使っていたりしない限り、この時点では docker コンテナのプロセスは1つも動いていないはずです:
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Hyperledger Fabric 環境の起動

ではローカルマシンに導入した Hyperledger Fabric 環境を起動します。これもコマンド1つです:
$ ./startFabric.sh

このコマンドが完了すると Hyperledger Fabric が起動したことになります。改めて docker コンテナのプロセスを確認すると、先程まで空だったコンテナプロセスがいくつか動いていることが確認できるはずです:
$ docker ps
CONTAINER ID        IMAGE               COMMAND             
6eb73fa9bc26        dev-peer0.org....   "chaincode -peer.a..."   
3ce2ff860034        hyperledger/f....   "peer node start -..."
e99420efba7f        hyperledger/f....   "orderer"
0dc1e0deaa92        hyperledger/f....   "sh -c 'fabric-ca-..."
c6bc1fe8a3f8        hyperledger/f....   "tini -- /docker-e..."

なお、起動中の Hyperledger Fabric を停止する場合は ./stopFabric.sh を実行します(以下の作業を続けるのであれば、しなくてもいいです):
$ ./stopFabric.sh


カードファイルの作成

ここからは以前の情報にはなかった、新しい仕様に関わる新しい箇所です。2018/02 時点では Hyperledger Fabric に接続する際に「カードファイル」と呼ばれる仕組みを使ってアクセスを行う必要があります(以前は「プロファイル」と呼ばれる仕組みを使った方法が用いられていました)。

作成&起動した Hyperledger Fabric 環境についてもカードファイルを使わないとアクセスしたり、操作することができません。まずはローカル環境(hlfv1)のデフォルト管理者となる PeerAdmin 用のカードファイルを作成します。サポートツールに含まれる以下のスクリプトを実行します:
$ ./createPeerAdminCard.sh

色々動いて、最後に "Command succeeded" と表示されれば成功で、/tmp/PeerAdmin@hlfv1.card というファイルが作られているので、このファイルを手元に(例えばホームディレクトリに)保存しておきます:
$ cp /tmp/PeerAdmin@hlfv1.card .

同時に、この時点で PeerAdmin@hlfv1 カードは有効に登録されています。登録済みのカードを一覧表示するには以下のコマンドを実行します:
$ composer card list

The following Business Network Cards are available:

Connection Profile: hlfv1
+--------------------+-----------+------------------+
| Card Name          | UserId    | Business Network |
+--------------------+-----------+------------------+
| PeerAdmin@hlfv1    | PeerAdmin |                  |
+--------------------+-----------+------------------+


Issue composer card list --name  to get details a specific card

Command succeeded


 ↑PeerAdmin@hlfv1 が確認できました。




・・・というわけで、2018/02 時点での仕様に合わせた Hyperledger Fabric & Composer 環境の構築手順と、カードファイルの準備手順までを紹介しました。ここまでできていると、composer コマンドとカードファイルを使ってビジネスネットワークを定義したり、起動したり、、、といったことができるようになります。そのための準備作業という意味合いでの紹介でした。


IBM Cloud(Bluemix) のアカウントを所有していると、マネージドサービスとして利用できる GitLab が使えるようになります。サーバーのインストールなどは不要で、プライベートリポジトリを作成することも可能です:
2018011701


使い勝手は GitLab そのものだと思ってください。Issues 管理の機能も使えますし、IBM Cloud の Continous Delivery サービスと連携した Delivery Pipeline による DevOps サービスの一部としても利用できるようになっています。アカウントをお持ちの方は、単にプライベートリポジトリが使える Git として考えるだけでも便利だと思うので、是非活用してください。


ところで、この IBM Cloud の Git を使って Java のアプリケーションコードを管理しようと、作成したリポジトリから Eclipse の Git 機能を使って clone を試みた際に、稀に以下のようなエラーメッセージに遭遇し、クローンに失敗することがあります:
  :
  :
!MESSAGE https://git.ng.bluemix.net/dotnsf/javatest.git: cannot open git-upload-pack
!STACK 0
org.eclipse.jgit.api.errors.TransportException: https://git.ng.bluemix.net/dotnsf/javatest.git: cannot open git-upload-pack
  at org.eclipse.jgit.api.LsRemoteCommand.call(LsRemoteCommand.java:196)
  at org.eclipse.egit.core.op.ListRemoteOperation.run(ListRemoteOperation.java:99)
  at org.eclipse.egit.ui.internal.clone.SourceBranchPage$8.run(SourceBranchPage.java:324)
  at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
Caused by: org.eclipse.jgit.errors.TransportException: https://git.ng.bluemix.net/dotnsf/javatest.git: cannot open git-upload-pack
  at org.eclipse.jgit.transport.TransportHttp.connect(TransportHttp.java:499)
  at org.eclipse.jgit.transport.TransportHttp.openFetch(TransportHttp.java:308)
  at org.eclipse.jgit.api.LsRemoteCommand.call(LsRemoteCommand.java:175)
  :
  :

「git-upload-pack がオープンできない」という耳慣れないエラーメッセージで、実はこのメッセージそのものからは原因の追求が難しいものでした。同じようなエラーに遭遇する人が現れた場合に備えて、自分の経験と回避策を紹介します。

エラーメッセージそのものからはわかりにくにのですが、実は直接の原因は暗号化方式の不一致による通信エラーでした。

まず上記で紹介した IBM Cloud の Git 機能を https 接続で使う場合の暗号化方式には TLS v1.2 を使う必要があります:
https://console.bluemix.net/docs/services/ContinuousDelivery/git_working.html#git_local


さて、Eclipse が使う Java のバージョンが 1.8 以上であれば、デフォルト設定のままで TLS v1.2 が使われます。したがってこの場合は何もしなくてもそのまま IBM Cloud の Git を利用することができます。

一方、Eclipse の Java バージョンが 1.7 以下だった場合、デフォルト設定で採用される通信方式は TLS v1.1 以下です。つまり条件を満たしていないことになります。そしてこの条件で Git に接続しようとすると上記のようなエラーメッセージが表示されてしまうのでした。


では、このエラーメッセージが出た場合の解決策はどうすればいいのでしょうか? 1つの方法としてJava のバージョンを 1.8 以上にするという簡単な方法があります。Java 1.8 以上であれば上記のように(デフォルトで) TLS v1.2 が使われるので、この条件を満たすことができるようになります。

ただ何らかの事情で Java 1.8 を導入するわけにはいかない場合もあると思っています。そのような場合は以下の1行を eclipse.ini に追加した上で Eclipse を起動する、という方法もあります:
  :
  :
-Dhttps.protocols=TLSv1.2

この記述により、Java が 1.7 以下であっても強制的に https 接続時の暗号化方式を TLS v1.2 に指定することができ、やはり上記のエラーを回避することができるようになります。


IBM Cloud 以外の Git でも、同様のエラーメッセージが出た場合にはこの対策が有効だと思っています。頭の片隅に入れながら、無料で便利な IBM Cloud の Git を是非使ってみてください。


これらの記事の続きです(シリーズとしては今回が最終回です):
Cloudant の便利な API (1) : バルクインサート
Cloudant の便利な API (2) : View Design Document
Cloudant の便利な API (3) : List Design Document

DBaaS である IBM Cloudant の便利で特徴的な API を紹介しています。前回までは Design Document の1つである View Design Document と List Design Document を紹介して、データベース内の特定の条件を満たすドキュメントデータだけを「ビュー」としてまとめ、かつそのビューの UI も格納ドキュメントの一部として定義する、という内容を紹介しました(47都道府県のドキュメントデータから海なし県だけを取り出して HTML の UI で表示する、というところまでを作りました):
2017100602

↑ https://username.cloudant.com/mydb/_design/nosea/_list/nosea/nosea にアクセスした結果(username は Cloudant インスタンスに接続するための username です)

最終回である今回は、この一覧からクリックした各ドキュメントも HTML で表示するための Show Design Document と、その API を紹介します。

前回のおさらいとして、このビューで表示される各ドキュメントをクリックすると、以下の URL に移動します(現時点ではエラーになります):
https://username.cloudant.com/mydb/_design/nosea/_show/nosea/(doc.id)

これは doc.id で示される id 値を持つドキュメントデータを nosea という Show Design Document の設計内容を使って表示する際の URL です(そして現時点では nosea という Show Design Document を定義していないためエラーになります)。

ではこの nosea Show Design Document を定義します。前回までに紹介した View Design Document と List Design Document を含む JSON の内容に赤字部分を加えて以下のようなドキュメント(nosea_show.json)を作ります:
{
 "language": "javascript",
 "views": {
  "nosea": {
   "map": "function(doc){ if( doc.code && [9,10,11,19,20,21,25,29].indexOf(doc.code) > -1 ){ emit( doc._id, {code:doc.code,prefecture:doc.prefecture,capital:doc.capital,lat:doc.lat,lng:doc.lng} ); } }"
  }
 },
 "lists": {
  "nosea": "function( head, row ){ start( { 'headers': { 'content-type': 'text/html' } } ); send( '<ul>' ); var row; while( row = getRow() ){  var url = '../../_show/nosea/';  send( ' <li><a href=\"' + url + row.id + '\">' + row.value.prefecture + '(' + row.value.capital + ')</a></li>' ); } send( '</ul>' );}"
 },
 "shows": {
  "nosea": "(function( doc, req ){ if( doc ){  var str = '<h2>' + doc.prefecture + '</h2><h3>' + doc.capital + '</h3><hr/>緯度: ' + doc.lat + '<br/>経度: ' + doc.lng;  return str; }else{  return 'empty'; }})"
 }
}

赤字部分が Show Desgin Document に相当する部分です。この中では同ファイル内の上位部分で定義された nosea ビューからクリックされた各ドキュメントが表示する際に実行される処理が記載されています。上記例では理解しやすさを優先して、ドキュメントの各属性(県名、県庁所在地名、緯度、経度)を単純に HTML で表示する内容にしています。

なお、この内容と同じファイル(nosea_show.json)をこちらからダウンロードできるよう用意しました:
https://raw.githubusercontent.com/dotnsf/samples/master/nosea_show.json


前回同様に、この JSON ファイルを指定して Design Document を更新します。まずは API で現在の Design Document を確認し、現在のリビジョンを確認します:
$ curl -u "username:password" -XGET "https://username.cloudant.com/mydb/_design/nosea"

{"_id":"_design/nosea","_rev":"YYYY..YYYY","language":"javascript", ... }

この例の場合の YYYY..YYYY 部分("_rev" の値)が現在のリビジョン ID なので、この値をダウンロードした nesea_show.json ファイルに追加します:
{
 "_rev": "YYYY..YYYY",
 "language": "javascript",
 "views": {
  "nosea": {
   "map": "function(doc){ if( doc.code && [9,10,11,19,20,21,25,29].indexOf(doc.code) > -1 ){ emit( doc._id, {code:doc.code,prefecture:doc.prefecture,capital:doc.capital,lat:doc.lat,lng:doc.lng} ); } }"
  }
 },
 "lists": {
  "nosea": "function( head, row ){ start( { 'headers': { 'content-type': 'text/html' } } ); send( '<ul>' ); var row; while( row = getRow() ){  var url = '../../_show/nosea/';  send( ' <li><a href=\"' + url + row.id + '\">' + row.value.prefecture + '(' + row.value.capital + ')</a></li>' ); } send( '</ul>' );}"
 },
 "shows": {
  "nosea": "(function( doc, req ){ if( doc ){  var str = '<h2>' + doc.prefecture + '</h2><h3>' + doc.capital + '</h3><hr/>緯度: ' + doc.lat + '<br/>経度: ' + doc.lng;  return str; }else{  return 'empty'; }})"
 }
}

これで更新用の nosea_show.json ファイルが完成しました。改めてこのファイルを指定して Design Document を更新します:
$ curl -u "username:password" -XPUT -H "Content-Type: application/json" "https://username.cloudant.com/mydb/_design/nosea" -d@nosea_show.json

{"ok":true, "id":_design/nosea", "rev":"ZZZZ..ZZZZ"}

これで Design Document が更新されました。改めてウェブブラウザで https://username.cloudant.com/mydb/_design/nosea/_list/nosea/nosea にアクセスすると、List Design Document で定義された内容に従って nosea ビューが表示されます(ここまでは前回と同様):
2017100602


そしていずれかのドキュメント(県名)をクリックすると、そのドキュメントデータが Show Design Document に定義された内容で表示されます。これで一覧から詳細情報まで表示するアプリケーションとして繋がりました!:
2017100604


先程は Design Document の理解のため比較的シンプルな Show Design Document を使いましたが、少し UI にも凝ったバージョンも用意しました:
https://raw.githubusercontent.com/dotnsf/samples/master/nosea_show2.json

こちらの JSON ファイルをダウンロードして、上記同様にリビジョン ID を調べて追加し、API で PUT すると、少しだけ凝った UI で海なし県の一覧と詳細画面を確認することができます(View Design Document は変更せずに、List Design Document と Show Design Document を変更したものです)。

nosea_show2.json を PUT した場合、ビューはテーブル形式で表示されます。県名または県庁所在地名がクリック可能になっています:
2017100605


クリックすると OpenStreetMap API を使って、その県庁所在地周辺の地図が表示されます。海なし県の海までの遠さを視覚的にも確認できる UI にしました(笑):
2017100606



4回に渡って IBM Cloudant の特徴的な Design Document とその API を中心に紹介してきました。以前にも触れましたが、IBM Cloudant のベースとなった CouchDB は IBM Notes/Domino と似た生まれであり、その設計思想などにも似た部分が多くあると感じています。私自身がノーツ大好きということもあってそんな Cloudant の特徴的な機能をまとめて紹介してみました。


これらの記事の続きです:
Cloudant の便利な API (1) : バルクインサート
Cloudant の便利な API (2) : View Design Document


DBaaS である IBM Cloudant の便利で特徴的な API を紹介しています。前回は Design Document の1つである View Design Document とその API を紹介して、データベース内の特定の条件を満たすドキュメントデータだけを「ビュー」としてまとめる方法を紹介しました。

今回紹介するのはやはり Design Document の1つで、「ビューの見た目を定義する」List Design Document です。前回の「ビュー」がドキュメント集合の条件を定義していたのに対して、今回の「リスト」は「ビューの見た目」を定義します。


一般的にデータベースを使ったウェブアプリケーションを作る場合、データベースサーバーにデータを格納した上で、そのデータを読み/書き/更新/検索して画面に表示する部分はアプリケーションサーバーに実装されることが多いです。しかし(HTTP をベースとした) REST API で動かす Cloudant は、その HTTP 部分を更に活用してデータの見た目に関わる部分までを定義・実装することができます。特に今回紹介する List Design Document ではデータの集合体であるビューの見た目を実装して格納します。個別の文書の見た目を実装する Show Design Document については次回紹介する予定です。


※余談ですが、この「見た目を定義する情報がドキュメントの一部として格納される」という点も「ノーツのビューやフォーム」に近い考え方や設計だと思っています。

このリスト(List)も Design Document の1つなので、ビューと同様に設計文書を用意します。前回紹介した View Design Document の JSON の内容に赤字部分を加えて以下のようなドキュメント(nosea_list.json)を作ります:

{
 "language": "javascript",
 "views": {
  "nosea": {
   "map": "function(doc){ if( 

doc.code && [9,10,11,19,20,21,25,29].indexOf(doc.code) > -1 ){ emit( doc._id, 

{code:doc.code,prefecture:doc.prefecture,capital:doc.capital} ); } }"
  }
 },
 "lists": {
  "nosea": "function( head, row ){ 

start( { 'headers': { 'content-type': 'text/html' } } ); send( '<ul>' ); var row; while( row = getRow() ){  var url = 

'../../_show/nosea/';  send( ' <li><a href=\"' + url + row.id + '\">' + row.value.prefecture + '(' + row.value.capital + ')

</a></li>' ); } send( '</ul>' );}"
 }
}

赤字部分が List Desgin Document に相当する部分です。この中では同ファイル内の上位部分で定義された nosea ビューを表示する際に実行される処理が記載されています。

なお、この内容と同じファイル(nosea_list.json)をこちらからダウンロードできるよう用意しました:
https://raw.githubusercontent.com/dotnsf/samples/master/nosea_list.json


赤字部分について簡単に内容を紹介すると、まず HTTP レスポンスヘッダとして 'Content-Type: text/html' を指定し、全体が HTML として返されるよう宣言しています。次に <ul> と </ul> の間が while でループ処理され、このビューに含まれる各文書(doc)の値を row として取り出します。そして
  <li><a href="../../_show/nosea/(doc.id)">県名(県庁所在地名)</a></li>
という <li> 要素を動的に作って <ul> と </ul> の間に挿入し、最後に全体を返しています。 要するに nosea ビューに含まれる海無し県の一覧を <ul> タグを使ってリスト表示している、というものです。

この JSON ファイルを指定して API を実行すれば List Design Document が作成される、、、のですが、もう1つだけ準備が必要です。今回作成する Design Document は前回作成した Design Document を上書きして保存する必要があります。そのため単にこのままのファイルを指定して API を実行しても(同一 ID への新規作成コマンドと解釈され)コンフリクトを起こしてしまい、更新できません。Cloudant の既存ドキュメントを更新する場合は既存ドキュメントのリビジョン ID を明示して実行する必要があるのでした。

というわけで、まずは API で現在の Design Document を確認し、現在のリビジョンを確認します。前回同様、コマンド内の username, password はそれぞれ Cloudant インスタンスに接続するための username, password で、実行結果を青字で表しています(以下同様):
$ curl -u "username:password" -XGET "https://username.cloudant.com/mydb/_design/nosea"

{"_id":"_design/nosea","_rev":"XXXX..XXXX","language":"javascript","views":{"nosea":{"map":"function(doc){ if( doc.code && [9,10,11,19,20,21,25,29].indexOf(doc.code) > -1 ){ emit( doc._id, {code:doc.code,prefecture:doc.prefecture,capital:doc.capital} ); } }"}}}

この例の場合の XXXX..XXXX 部分("_rev" の値)が現在のリビジョンIDです。nosea_list.json をテキストエディタで開いて、この値を使って以下のように書き換えます:
{
 "_rev": "xxxx..xxxx",
"language": "javascript", "views": { "nosea": { "map": "function(doc){ if( doc.code && [9,10,11,19,20,21,25,29].indexOf(doc.code) > -1 ){ emit( doc._id, {code:doc.code,prefecture:doc.prefecture,capital:doc.capital} ); } }" } }, "lists": { "nosea": "function( head, row ){ start( { 'headers': { 'content-type': 'text/html' } } ); send( '<ul>' ); var row; while( row = getRow() ){ var url = '../../_show/nosea/'; send( ' <li><a href=\"' + url + row.id + '\">' + row.value.prefecture + '(' + row.value.capital + ') </a></li>' ); } send( '</ul>' );}" } }

これで更新用の nosea_list.json ファイルが完成しました。改めてこのファイルを指定して Design Document を更新します:
$ curl -u "username:password" -XPUT -H "Content-Type: application/json" "https://username.cloudant.com/mydb/_design/nosea" -d@nosea_list.json

{"ok":true, "id":_design/nosea", "rev":"YYYY..YYYY"}

これで Design Document が更新されました。この時点でダッシュボードの nosea ビューを確認すると・・・一見、何も変わっていないようにみえます:
2017100601


しかしウェブブラウザで https://username.cloudant.com/mydb/_design/nosea/_list/nosea/nosea にアクセスすると、List Design Document で定義された内容に従って nosea ビューが表示されます。結果としてこのような画面が表示されます:
2017100602


これが Cloudant(CouchDB) の特徴ともいえる Design Document の機能です。通常であれば別途アプリケーションサーバーを用意した上で UI やロジックを実現するのですが、Cloudant の場合は Design Document を使うことで Cloudant の REST API(HTTP) の機能を使って UI を実現することができるようになるのでした。 ただ上のUIはシンプルすぎるので実用段階ではもう少しちゃんとしたほうがいいとは思います(苦笑)。

なお、この結果表示されている画面の各海なし都道府県へのリンクをクリックすると、以下のようなエラーになります:
2017100603


これはビューの UI とリンクまでは作成したのですが、各ドキュメントの内容(UI)を表示する Design Document についてはまだ作成していないために(リンク先が見当たらずに)エラーとなっているのでした。というわけで、次回は各ドキュメントの UI を定義する Show Design Document とその API について紹介し、各ドキュメントの内容まで表示できるようなアプリケーションを完成させる予定です。



このページのトップヘ