nodeでWebアプリを開発するときに考えること

僕は、全体を俯瞰して作り出すので遅いのだけれども、トータルとして同じくらいのスピードになるかなと思って、新しい言語やフレームワークを使うときは、まずは全体で必要になりそうな技術であったり、問題点を潰すことにしています。

フレームワーク

nodeのフレームワークは、たくさんありすぎてどれを使っていいのやら、という状況だけれども express 使っておけば良いというのが僕の中での結論。 ルーティング、テンプレート、セッション管理といった基本的な機能を簡単に使える(connectが素晴らしいというのもあるけど)ので、複雑なことをしたければあとは自分で頑張るほうがいいと思う。

それに、全部読みきれる量であるということ。 使うライブラリのコードを読みきれるというのはすごい重要。フレームワークでサポートしていないことをしたくなったときにどこに手を入れて良いのかがすぐに判断できるから。 また、expressのテストコードはmochaを使っているので、本体と合わせて読むと、どうやってテストコード書けばいいかも勉強できて良い。

O/Rマッパー

RDBMSを使ってそこそこの規模のWebアプリを書こうと思うと、O/Rマッパーがあるとすっきりする。が、探してみるとActiveRecordのような決定的なものがない。 ぱっと見でよさそうなのが、node-orm2

https://github.com/dresende/node-orm2

基本的なクエリに加えて集計関数も投げられるし、has-oneとかhas-manyといった関連も定義でき、フックも充実、さらにexpressとも相性がいい。 Rails界に住んでる人は、モデル毎にファイルを分けて定義したくなるので、手動でロードしないといけないのでちょっと面倒。

var orm = require('orm'),
    fs = require('fs');

var dbConfig = JSON.parse(fs.readFileSync(__dirname + '/database.json'));
var db = orm.connect(dbConfig.dev);
fs.readdir(__dirname + "/models", function(err, models) {
  if (err) {
    console.log(err);
    return;
  }
  models.forEach(function(model, i) {
    db.load(model, function(err) {
      console.log(err);
    });
  });
});

一般的にnodeでRDBMSを操作することはやはり少ないのかなぁ。スロークエリ頻発するともはや非同期IOは意味をなさなくなるというところから、mongoやCouch、Redisを積極的に使う方針にしたほうがよいのだろうか。

migration

RDBMS使うなら、migrationの機構がないと死ねる。node-db-migrateが使いやすい。Rails流。up/downで操作、データベースにmigrationsテーブル作って管理するところなど。

https://github.com/nearinfinity/node-db-migrate

上記のnode-orm2と相性はまぁまぁ。唯一ぐんにょり来るのが、設定ファイルのプロパティ名が違っていること。 node-orm2では、protocolだがnode-db-migrateはdriverになっている。database.jsonで両方記述しておくとうまくいくが、ぐんにょり来る。 あと、Rails界の人は、

  • updated_atcreated_atは必ず自分で定義しないといけない
  • サロゲートキーも自分で定義(idも自動付与されず自分でPK、AUTO_INCREMENTを指定する)

に注意。

auto loader

hotnodeが今のところ快適に使えている。 コヒスク使う人は、hotcoffeeコマンドで。 シングルページアプリケーション程度の規模なら問題なし。

https://github.com/saschagehlich/hotnode

デバッガ

とりあえず、node-inspector使っておけ、らしい。

https://github.com/dannycoates/node-inspector

Webkitブラウザ上でサーバサイドのコードをデバッグ実行できるので死ぬほど便利。一度使うと便利すぎてないと生きていけなくなる。 上記のhotnodeとも組み合わせて使える。

$ hotnode --debug app.js # アプリ起動
$ node-inspector # 別ターミナルで実行してChromeなどにアクセスする

ホスティング

普通のWebアプリなら迷わずHerokuだけれども、たとえばWebSocketを使いたい場合Herokuはまだサポートしていない。

https://devcenter.heroku.com/articles/using-socket-io-with-node-js-on-heroku

Herokuは1Dynoなら無料で公開できる(ただし750時間までなので注意)ので、これほどまでに使いやすいPaaSはないので諦めるのは辛いところ。 WebSocketの代わりにロングポーリングでも良いのだけれども、iPhoneiPadだと通信中のぐるぐるが回ったままで、気にする人は気にするので気持ち悪さを与えて結果として使わないということがあるので、なるべくWebSocket使いたい。

とりあえずは、Herokuで作り問題が出て来て(お金に余裕のある人は)、nodejitsuやAWS、VPSあたりを借りるがいいのでは。

デプロイ

nodeアプリを動かすときに、Heroku や nodejitsu といったPaaS使わない場合、手動(capコマンド実行等)/自動(git pushトリガー, jenkinsトリガー)問わずproduction環境にデプロイする必要がある。

Stack Overflowの解答を眺めていると、Capistranoを使っている人が割と多い。

プロセス管理

nodeは、内部でエラーが発生すると、落ちる。イコールサービスが止まる。なので、基本的に自動で上げるためのプロセス管理が必要になる。 まぁこれはいくらでもあるので、monit、god、supervisor等慣れたものを使うのが良いと思う。

あとは、node製のものとして、foreverがある。 nodejitsuはforever使っているとのこと。 Stack Overflowでの解答も「とりあえずforever」という意見が多い。