node.jsのMVCフレームワークSails.jsを使ってみた

久々の記事ですね。引越しがあったので、バタバタしてました。

という事でさっそく。
最近はてブ等ででフレームワークのSails.jsの記事があり、ちょっと気になってました。

Sails.jsは、ExpressJSをベースにしているそうですが、ルーティングの自動化や認証周りが楽になっているようです。

基本的にRe* Programmingさんの記事の後追いなんですが、いくつか戸惑った点などがあったので、まとめておきます。

まず、Sails.jsのバージョンがnpmjs.org上では、まだv0.8.895だという点です。

これに関しては、GitHubからの取得で最新版のv0.8.91に置き換えてしまいます。


~/binは$PATH上で/usr/local/share/npm/binよりも前に設定しておきます。

$ git clone git://github.com/balderdashy/sails.git
$ cd sails/ && npm install
$ ln -s bin/sails.js ~/bin/sails

プロジェクトを作ります。

$ sails new sails_oar
$ cd sails_oar && npm install

この時点でプロジェクト内の/node_modules/sailsはnpmjs.orgのものになってしまいます。
これを~/binに置いたものへのシンボリックリンクにします。

$ cd node_modules
$ rm -fr sails
$ ln -s ~/bin/sails.git sails

これだけだと以下のエラーになってしまいました。

$ sails lift

/Users/****/bin/sails.git/lib/sails.js:97
	if (configOverride.dev && configOverride.prod) {
	                  ^
TypeError: Cannot read property 'dev' of undefined
    at loadSails (/Users/****/bin/sails.git/lib/sails.js:97:20)
    at Object.liftSails [as lift] (/Users/****/bin/sails.git/lib/sails.js:58:2)
    at Object.<anonymous> (/usr/local/share/npm/lib/node_modules/sails/bin/sails.js:121:70)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:901:3

普通に

npm install sails -g

でインストールしているため、/usr/local/share/npm/lib/node_modules/sailsを見に行ってしまっています。これも置き換えます。

$ cd /usr/local/share/npm/lib/node_modules
$ mv sails sails.bak
$ ln -s ~/bin/sails.git sails

(というか、ここまでやるならこっちは完全に置き換えても良いかもです)

実行します。

$ sails lift
error: This app specifies Sails version 0.8.895, but local node_modules/sails version is 0.8.91  
error: You may consider reinstalling Sails locally (npm install sails@0.8.895).  
debug: Starting server in /Users/****/Sites/qcal/sails_oar...  
   info  - socket.io started
debug: 
debug:   
debug:   
debug:   
debug:                    <|  
debug:                     |  
debug:                 \\____//  
debug: --___---___--___---___--___---___  
debug: --___---___--___---___--___---___  
debug:   
debug: Sails (v0.8.91)  
debug: Sails lifted on port 1337 in development mode.  
debug: 
debug: ( to see your app, visit: http://localhost:1337 )  

バージョンのエラー表示があるので、一応修正しておきます。

{
  "name": "sails_oar",
  "private": true,
  "version": "0.0.0",
  "description": "a Sails application",
  "dependencies": {
    "sails": "0.8.91",
    "sails-mysql": "~0.7.8"
  },
  "scripts": {
    "start": "node .app.js",
    "debug": "node debug .app.js"
  },
  "main": ".app.js",
  "repository": "",
  "author": "",
  "license": "MIT"
}

次に戸惑ったのが、ユーザ認証のconfig/policies.js。

分かってしまえば単純な事だったんですが、Re* Programmingさんの記事は詳しく書かれていなかったので、少し考え込みました。

元のpolicies.jsは以下のようになっています。

/**
* Policy defines middleware that is run before each controller/controller.
* Any policy dropped into the /middleware directory is made globally available through sails.middleware
* Below, use the string name of the middleware
*/
module.exports.policies = {
 
    // Default policy (allow public access)
    '*': true
 
    /** Example mapping: 
    someController: {
 
        // Apply the "authenticated" policy to all actions
        '*': 'authenticated',
 
        // For someAction, apply 'somePolicy' instead
        someAction: 'somePolicy'
    }
    */
};

んで、コントローラーに対して認証をかける場合、「someController」と書いてあったので、/api/controllers/内のコントローラー(例えば)「UserController」なんだと思っていたんですが、どうやらリクエストするURL側の表記である「user」のようです。
こんな感じ。

module.exports.policies = {

	// Default policy (allow public access)
	'*': true,

	user: {
		'*': true,
		create: 'authenticated',
		destroy: 'authenticated'
	},

	auth: {
		// Apply the "authenticated" policy to all actions
		'*': true
	}
};

それから最後、これは/api/policies/authenticated.jsを見れば分かりますが、認証を通ったと判断させるには、Re* Programmingさんの記事には

session.authenticated = true;

とありますが、正しくは

req.session.authenticated = true;

です。

全体的に、ExpressJSよりも楽で使いやすそうです。ExpressJSの知識も大体は使えそうですし。