Node.js とそのフレームワークである Express v4 を活用し、Ajaxからアクセスする簡単サンプルを Eclipse で作って、クラウドの Bluemix で動かしてみましょう。次のサンプルも考慮し、Cloudantも一緒にセットアップします。完成すれば以下のような画面になり、下に名前を入力すると、上の表に追加されます。
Bluemixの Node.jsと Cloudant のセットアップ
リンク先のBluemix にログインし、クラウド環境を構築します。(=>Bluemixを利用したこと無い方は、こちら)
Bluemix の初期画面から、[+ アプリの作成] で [Web]、[SDK for Node.js] と選び、[新規アプリの名前] で自分の好きな名前を入力して [完了] してください。(ここでは、「BMSampleC」という名前にしていますが、同じ名前は登録できないので、変えてください)
[どのようにコーディングを開始するか] は [GIT] をクリックした上で、画面一番下の [アプリの概要の表示] をクリックしてください。
そこの [+ サービスまたはAPIの追加] をクリックし、Bluemixの数あるサービスの中から、[データ管理] の [Cloudant NoSQL DB] をクリックし、[作成] してください。ポップアップが出たら、[再ステージング] をクリックしてください。「ダッシュボード」 に戻り、Cloudantが追加されていると思います。これでもう、Bluemix のクラウド側は Ready! です。
ダッシュボードの右上に、[GITの追加] がありますので、そこをクリックしてください。[GITリポジトリーの作成] で [作成] とし、「ダッシュボード」 に戻ると先ほど [GITの追加] と表示されていたところが、[GIT URL:] になります。この右のURL (「https://hub.jazz.net/git/xxxx/BMSampleC」 など)をクリップボードにコピーしておきます。
Bluemix上の DevOpsサービスで開発を継続しても良いのですが、今回はローカルPCでのテストを試すために、自分のPCのEclipseで開発してみます。(=>Eclipseの導入はまずこちら)
Eclipseの設定と、ローカルPCへのNode.jsの導入
Eclipseの [ファイル]メニューで [インポート] [Git] [Gitからプロジェクト] で、[URIの複製] のURIに、上でコピーしたURLを貼り付けます。下の[ユーザー:][パスワード:]は、BluemixのユーザーID/パスワード(IBM ID)か、JazzHubのを入力して、[次へ]をクリック。[master]がチェックされている状態で[次へ]をクリックし、ディレクトリの変更が無ければそのまま[次へ]で、[一般的なプロジェクトとしてインポート]を選択し[次へ]に行き[完了]をクリックします。
Eclispeの「プロジェクト・エクスプローラ」上に、Bluemix上のGITのプロジェクトがインポートされ、表示されているはずです。
次に、Eclipseでの Node.js開発に便利な、nodeclipse を導入します。Eclipseメニューの[ヘルプ] [Eclipseマーケットプレース] をクリックしてマーケットプレースを立ち上げ、[検索:] に、「nodeclipse」 と入力してください(”e”の数に注意!)。リストの中から、「Nodeclipse .17.plus」 の[インストール] ボタンをクリックし導入します。(=>参考)
[選択されたフィーチャー] は基本全て選択の状態で、[確認] [使用条件に同意] にチェックし、[完了] してください。
次に、Note.js 本体 (JavaScriptエンジンと、npm) を導入します。以下からダウンロード (INSTALL) してください。node-xxxx.msi がダウンロードされたら実行し、基本そのままのデフォルト設定で導入します。
Eclipseで Node.jsの実行
Bluemixから取得したサンプルのプロジェクトを Eclipseで開き(上の例は、BMSampleC)、「package.json」 を右クリックします。そこで、[実行] [npm install] で、package.json で実行すると、package.json に記述された、このサンプルに必要なモジュールが全て自動的にダウンロードされ、セットアップされます。(npmはNode.jsに含まれているため、ローカルへの導入と、PATHがきれていることが前提)
次に同様に、サンプルの中の、「app.js」 を右クリックし、[実行] [Node Application] をクリックすることで、Node.js がローカルPCで実行されます。(エラーの場合は、下の章を参照)
実行後に、「Port番号 3000 で実行」 などと英語で表示されますので、Eclipseの地球アイコンの「Webブラウザーを開く」か、通常のブラウザで以下のURLをアクセスして、実行結果を表示してください。
http://localhost:3000/
起動したサーバーを止めるには、Eclipseの下の [コンソール] のペインで [選択されたコンソールの表示] アイコンで起動した 「Node.js process」 を選択して表示し、赤い四角の [終了] ボタンを押すと停止します。停止すると、サーバーを再度実行できます。
Node.jsの実行でエラーが表示された場合
「app.js」の実行で、Eclipseのコンソールに以下のエラーが表示される場合があります。
path.js:233
throw new TypeError( ‘Arguments to path.join must be strings’);
これは、サンプルで使われている、「cfenv」 というCloud Foundryを使って環境情報を取得する部品のバージョン不整合エラーです。
「app.js」 を以下のように「cfenv」を使わないように書き換えて、保存して再度実行してみてください。(これを動かさなくても次のステップに行けます)
// This application uses express as it's web server // for more info, see: http://expressjs.com var express = require('express'); // create a new express server var app = express(); // serve the files out of ./public as our main files app.use(express.static(__dirname + '/public')); //------ //There are many useful environment variables available. //VCAP_APPLICATION contains useful information. var appInfo = JSON.parse(process.env.VCAP_APPLICATION || "{}"); var services = JSON.parse(process.env.VCAP_SERVICES || "{}"); var host = (process.env.VCAP_APP_HOST || 'localhost'); var port = (process.env.VCAP_APP_PORT || 3000); //Start server app.listen(port, host); console.log('App started on port ' + port);
Ajaxを使う Node.jsサンプル・アプリケーションの開発
次に、サンプル・アプリケーションを Ajaxを活用するよう変更します。このサンプルでは 「express」 のv4.x に加え、「body-parser」 「date-utils」 というオープンソースを使います。
まずEclipseのプロジェクト・エクスプローラーで、「package.json」 を開き、以下のように変更してください。
{ "name": "Nodejs_Start", "version": "1.0.0", "description": "Sample nodejs + ajax app for Bluemix", "scripts": { "start": "node app.js" }, "dependencies": { "express": "4.12.x", "body-parser": "*", "date-utils": "*" }, "repository": {} }
次にEclipseでその 「package.json」 を右クリックし、[実行] [npm install] をクリックすると、ローカルPCで Node.js のパッケージ管理機能である 「npm」 が必要なモジュールを一通りダウンロードしてくれます。「node_modules」 フォルダに保管されるため、プロジェクト・エクスプローラーのプロジェクトを [リフレッシュ] して確認してください。
最初に起動されるサーバー側の 「app.js」 は、以下のように変更してください。汎用アプリケーション・フレームワークの 「express」 と、ブラウザとサーバーでやり取りするデータを取得するための 「body-parser」 と、日付を取得するための 「date-utils」 をセットアップし、「app.post」 でブラウザからPOSTで送られてきたデータに日付を追加し、「res.send」 で返します。
// expressアプリ・フレームワークの設定 var express = require('express'); var app = express(); // POSTパラメータ取得用 body-parser設定 (express4からurlencoded()とjson()必要) var bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); // index.htmlの /public ディレクトリ設定 app.use(express.static(__dirname + '/public')); // Date()で現在時刻を取得するためのユーティリティ var dateutil = require('date-utils'); app.post('/', function(req, res){ var date = new Date(); var now = date.toFormat("YYYY/MM/DD HH24:MI:SS"); req.body.date = now; console.log('app.js req.body: ' + JSON.stringify(req.body)); res.send(req.body); }); //環境変数にポート番号が無ければ、port=3000 設定 var port = (process.env.VCAP_APP_PORT || 3000); // サーバー開始 app.listen(port); console.log('App started on port ' + port);
Node.jsにデータを送る Ajax画面サンプルの開発
次に画面側を作成します。プロジェクトエクスプローラの 「public」フォルダにある、「index.html」 を以下のように変更してください。
「script」で、ブラウザ上で動かすJavaScriptである 「js/ui_item.js」を指定しています。 前半の 「dataTable」 が表示する表で、中央の 「dataItems」 に後からデータの行を追加します。一番下の 「form」 のところが、データ追加用ボタンです。
<html>
<head>
<title>jsonp test</title>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="js/ui_item.js"></script>
</head>
<body>
<table id="dataTable" border="1">
<thead>
<tr>
<th>時間</th><th>項目</th>
</tr>
</thead>
<tbody id='tableItems'></tbody>
</table><br>
<div id="form">
<br>
<span>項目名: </span><span><input type="text" id="item1"></span><br>
<button value="追加" id="add">追加</button>
<br>
</div>
</body>
</html>
その index.html から呼ばれるJavaScriptを追加しますので、「public」フォルダを右クリックし、 [新規追加] [フォルダ] で、「js」 を追加し、その下に、[新規追加] [ファイル] で、「ui_items.js」 を追加し中に以下をコピー&ペーストしてください。
最初の 「showTable」 が、画面の表に一行追加する部分で、「#add」 部分が「追加」ボタンが押された際に呼び出され、「$.ajax」 部分でサーバーにデータがPOST送信されます。
// ui_item.js ブラウザUI用 JavaScript (index.htmlより呼ばれる)
$(function(){
console.log('ui_item.js in');
// サーバから取得したデータを、htmlテーブルに追加
var showTable = function(data) {
$("#tableItems").append("<tr></tr>")
.find("tr:last")
.append("<td>" + data.date + "</td>")
.append("<td>" + data.item1 + "</td>")
};
// 追加ボタン(index.htmlのid=add)押下時 実行
$("#add").click(function(e){
e.preventDefault();
var param = {};
param.item1 = $("#item1").val() || "";
// POSTでのajaxコールで、サーバーのapp.jsのapp.post呼び出し
$.ajax({
type: 'POST',
data: JSON.stringify(param),
contentType: 'application/json',
url: '/',
success: function(data) {
console.log('add success: ' + JSON.stringify(data));
showTable(data);
},
error: function(data) { console.log('error ' + JSON.stringify(data)); }
});
// 入力項目名を空白に
$("#item1").val('');
});
});
これらのファイルを追加すると、以下のようなフォルダ構成になります。
稼動テスト
保管が終了したら、まず Eclipse上で 「app.js」 を右クリックし [実行] [Node.js] を実行してください。コンソール上に ポート3000 で稼動していると英語で表示されたら、サーバーは稼動しています。ブラウザで以下のURLをアクセスして、実行結果を表示してください。一番上のWeb画面が表示されるはずです。
http://localhost:3000/
=> 次の記事は、このサンプルの Node.js側で、データを Cloudant DBに格納します!
補足)ローカルEclipseと、クラウドBluemixのコードの同期
最後にローカルPCのEclipseで変更したコードを、クラウド上のBluemixと同期します。Eclipseの [プロジェクト・エクスプローラー] のプロジェクトを右クリックし、、[コミット] を実行します。[コミット・メッセージ] にコメントを記入して、[ファイル] の右の [全て選択] アイコンをクリックし、 [コミット] ボタンを押します。(=>詳しくはこちら参照)
[チーム同期化] パースペクティブの、[同期化]タブのアイコンのうち、左から4番目の矢印がオレンジ色の [プッシュ] をクリックし、ローカルの更新をリモートのクラウドにプッシュします。
Bluemix上のGITビューで、[着信] が来ているはずですので、真ん中の上向き矢印アイコン [ブランチのコンテンツをアクティブ・ブランチにマージ] をクリックします。上に「成功しました」と表示されれば、変更の全体への反映が完了です。(=>詳しくはこちら参照)
これでBluemix上に反映することができましたので、Bluemixの 「アプリケーションURLを開く」 か、「経路」 をクリックして稼動を確認してください!
なお、Bluemix 上に反映された変更を、他のEclipse と同期する場合は、まずローカルPCのEclispeで同様に、プロジェクトに対し [チーム] [ワークスペース同期化] を実行します。プロジェクトに対し、[マージ] を実行すると、ローカルのソースコードと、リモート(Bluemix)のコードの比較が表示されます。そこで、[ソースの比較] タブの左から2番目のアイコンで [双方向比較 (上位を無視)] をクリックします。次に、左から3番目のアイコンの [右から左に全ての非競合をコピー] か、4番目の [右から左に現在の非競合をコピー] で一つずつ反映するかを選択し、実行してください。サーバーのコードとマージできますので、[保管] してください。
単純にBluemixからコードを取得する場合は、[チーム同期化] パースペクティブの [同期化] タブの [プル] を実行してください。
ソースコードが何かのはずみでおかしくなり、元のバージョンに戻したい場合は、そのファイルに対し右クリックし、[置換] [ローカルヒストリーの前回のものと置換] を実行し元に戻してください。