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を公開しました。