express-resourceが面倒を見てくれる。REST APIの場合はビューと呼ぶほどのものではないが、APIの出力形式をXML、JSONと複数対応するにはコンテントネゴシエーションが強力なビュー機能を提供してくれると言える。
MVCアプリケーションを作る際、コントローラ(C)とビュー(V)は前回紹介したさて、今回はモデル(M)に相当する部分を作る際に欠かせないSequelizeを紹介しよう。 Sequelizeを使うと、DBのスキーマやデータを、node.jsアプリケーション内でJavaScriptオブジェクトとして扱えるようになる。いわゆるO/Rマッパーを実現してくれる。MySQL、SQLite、 PostgreSQLと主なオープンソースのRDBMSはサポートされており、RDBMS毎に微妙に異なるSQLの方言などを吸収してくれるので、仮に開発過程でRDBMSを乗り換えることがあったとしても、アプリ側のコードに大掛かりな修正が生じなくて済む。
早速インストールしてみる。前回のpackage.json
を引き続き編集してsequelize
を追加したら、npm install
を実行する。
{ "name": "application-name" , "version": "0.0.1" , "private": true , "dependencies": { "express": "2.5.8" , "express-resource": "latest" , "sequelize": "latest" , "jade": ">= 0.0.1" } }
続いて、app.js
でSequelizeをインスタンス化するコードを追加する。
var express = require('express') , resource = require('express-resource') , Sequelize = require('sequelize') , app = module.exports = express.createServer(); sequelize = new Sequelize('database', 'username', 'password'); app.resource('users', require('./routes/users'), { id: 'id' });
と、サンプルではこう書かれることが多いが、データベースの接続情報をapp.js
にハードコーディングするのはまったく実用的ではない。production
版かdevelopment
版かによって環境が変わるのが普通なので、データベースの接続情報は別の設定ファイルに書くようにしたい。
そこで、node-configをインストールする。再度、package.json
を編集してnpm install
を実行しよう。
{ "name": "application-name" , "version": "0.0.1" , "private": true , "dependencies": { "express": "2.5.8" , "express-resource": "latest" , "sequelize": "latest" , "config": "latest" , "jade": ">= 0.0.1" } }
モジュール名はnode-configだが、NPMに登録されているパッケージ名は単にconfigなので注意。
node-configは、config
ディレクトリ内にある以下のファイルを順に読み込むようになっている。読み込むディレクトリは環境変数NODE_CONFIG_DIR
で変更することもできる。
default.EXT hostname.EXT deployment.EXT hostname-deployment.EXT runtime.json
EXT
の部分は設定ファイルの書式によって変わり、json
、js
、yaml
、coffee
がサポートされている。設定をホスト名で分けることができるのは、痒いところに手が届く感じで嬉しい。
Sequelizeのコンストラクタに渡す引数を、config/development.json
に書いておく。
{ "sequelize": { "database": "test" , "username": "h2plus" , "password": "password" , "options": { "host": "localhost" , "dialect": "mysql" , "pool": { "maxConnections": 5 , "maxIdleTime": 30 } } } }
先ほどapp.js
でSequelizeのインスタンス化をするときに、options
は渡していなかったが、Sequelizeの4番目のコンストラクタ引数で細かい設定オプションを渡すことができる。詳しくは本家のUsageに書いてあるが、MySQL限定でコネクションプーリングも使えるようだ。
めでたくデータベースの接続情報を設定ファイルに分離できたわけだが、Sequelizeをインスタンス化するコードをapp.js
に直接書きたくないので、自前で専用のモジュールを作ってしまおう。アプリケーションのディレクトリ構造はこんな感じになる。
myrest/ ├── app.js ├── config/ │ └── development.json ├── libs/ │ └── dbconn/ │ └── index.js ├── node_modules/ ├── package.json ├── public/ │ ├── images/ │ ├── javascripts/ │ └── stylesheets/ │ └── style.css ├── routes │ ├── index.js │ └── users.js └── views ├── index.jade └── layout.jade
libs/dbconn/index.js
には以下のようなコードを書く。
/** * config.sequelize = { * database: <string> * , username: <string> * , password: <string> * , options: <object> * }; */ module.exports = function(config) { var Sequelize = require('sequelize') , params = config.sequelize || {}; params.options = params.options || {}; console.log('Sequelize connecting to %s on %s as %s', params.database, params.options.host || 'localhost', params.username); return new Sequelize(params.database, params.username, params.password, params.options); };
app.js
ではSequelizeを直接インスタンス化せずに、このdbconn
モジュールを使うようにする。
var express = require('express') , resource = require('express-resource') , config = require('config') , sequelize = require('dbconn')(config) , app = module.exports = express.createServer(); app.resource('users', require('./routes/users'), { id: 'id' });
スッキリ!
自前で作ったモジュールは、デフォルトではnode.js
は読み込んでくれないので、package.json
を編集して、起動時に環境変数NODE_PATH
で指定してやる。
{ "name": "application-name" , "version": "0.0.1" , "private": true , "dependencies": { "express": "2.5.8" , "express-resource": "latest" , "sequelize": "latest" , "config": "latest" , "jade": ">= 0.0.1" } , "scripts": { "start": "NODE_PATH=libs node app.js" } }
package.json
にscripts.start
を書いておくと、通常のnode.jsの起動コマンド(node app.js
)を使わずに、npm start
でnode.jsを起動できるようになる。環境変数なんかを設定する場合はこっちの方が断然便利。
Sequelizeを使うための準備だけなのに、だいぶ長くなってしまったので中編に続く…
3 コメント