express-resourceを使って効率よくREST APIを実装できるようにするためのexprestというnodeパッケージをNPMで公開してみた。と言っても、リリースしたのは2ヶ月も前の話。使い方などはREADME.mdに英語で書いておいたが、英語が苦手な人のために日本語の対訳を書いておこう。
インストール
通常のNPMパッケージと同じようにnpm installでインストール。
$ npm install exprest
使用方法
exprestが提供するのはconfigure()という関数のみ。
exprest.configure(app [,opts]);
appには、express.HTTPServerオブジェクトかexpress.HTTPSServerを渡すように。もちろん、exprest#configure()を呼ぶ前にexpress-resourceをrequire()で読み込んでおくこと。
一番シンプルな使い方はこんな感じ。
var express = require('express')
, resource = require('express-resource')
, exprest = require('exprest')
, app = express.createServer();
exprest.configure(app);
ルーティングのコードは一切書く必要がない。アプリケーションのルートディレクトリにresourcesというディレクトリを作って、そこに以下のようなresourceモジュールを実装しておけば、ルーティングはexprestが面倒を見てくれるようになっている。
module.exports = {
index: function(req, res) {
res.end('index');
}
, new: function(req, res) {
res.end('new');
}
, create: function(req, res) {
res.end('create');
}
, show: function(req, res) {
res.end('show');
}
, edit: function(req, res) {
res.end('edit');
}
, update: function(req, res) {
res.end('update');
}
, destroy: function(req, res) {
res.end('destroy');
}
};
resourceモジュールのファイル名がREST APIで提供するリソースへのパスを表すようになっている。例えば、resource/users.jsというモジュールを実装したら、exprestが/users/*に対するリクエストをルーティングしてくれる。
オプション
configure()関数の第2引数optsを使って、exprestの振る舞いをカスタマイズすることができる。optsを省略した場合は、以下のデフォルト値が適用される。
{
basedir: 'resources'
, root: '/'
, vars: {}
, varsKey: 'vars'
, checkAuth: undefined
, defaults: {}
}
- basedir(文字列)
resourceモジュールの配置先となるディレクトリ。 - root(文字列)
REST APIのルートとなる仮想ディレクトリ。
例えば、{ root: '/api' }を渡すと/api/users/*へのリクエストはresources/users.jsにマップされる。 - vars(オブジェクト)
http.ServerRequestを介してAPIに渡す変数。
このオプションにより、resourceモジュール間で変数を共有することができる。例えば、app.js内でexprest#configure()を呼び出すコードがあって、app.jsのローカル変数をresourceモジュールに引き渡したかったとしよう。グローバル変数(GLOBAL)を使うという手もあるが、どのようなプログラムでもグローバル変数はできるだけ避けたいものである。varsオプションは、このような変数をhttp.ServerRequest経由で引き渡すためのものだ。サンプルコードを見るのがわかりやすいだろう。
// app.js var express = require('express') , resource = require('express-resource') , exprest = require('exprest') , mysql = require('mysql').createConnection(...) , app = express.createServer(); exprest.configure(app, { vars: { mysql: mysql } }); // resources/users.js module.exports = { index: function(req, res) { var mysql = req.vars.mysql; // Passed by exprest mysql.query('SELECT * FROM users', function(err, users) { ... }); } };resourceモジュール(サンプルではusersモジュール)がDB操作を伴うような場合、DB接続を保持するオブジェクト(サンプルではapp.js内のmysqlオブジェクト)をすべてのresourceモジュールで共有したいケースはよくある。resourceモジュールはapp.jsとは別ファイルに実装されているので、mysqlオブジェクトをapp.jsから直接的にresourceモジュールに引き渡すことはできないが、exprest.configure()でvarsオプションにオブジェクトを引き渡すと、resourceモジュールの各アクションメソッドの引数req.varsを介してアクセスすることができるようになる。 - varsKey(文字列)
varsで渡したオブジェクトを、http.ServerRequestにマップする際のキーを指定する。例えば、varsKeyに"hoge"を指定した場合、resourceモジュールの各アクションメソッドでは、req.hogeを介してアクセスすることになる。 - checkAuth(関数)
checkAuthオプションを指定すると、exprestはルーティングに先立ってcheckAuthに渡された関数を呼び出すようになる。これにより、APIに対する認証フィルターを設けることができる。checkAuthで指定する関数は、現在のセッションが認証済みかどうかを示す真偽値を返すように実装しなければならない。checkAuthがtrueを返した場合、exprestはそのままAPIにルーティングする。falseを返した場合、exprestは何もしない。checkAuthはfalseを返す前に、クライアントにレスポンスを送らなければならない。以下はセッションを用いて認証状態を管理するサンプル。
var express = require('express') , resource = require('express-resource') , exprest = require('exprest') , app = express.createServer(); exprest.configure(app, { checkAuth: function(req, res) { if(req.session.user_id) { return true; } res.send(403); return false; } }); - defaults(オブジェクト)
express-resourceに引き渡すオプション。
exprestは廃止しました。代わりにexprest4を公開しました。