高仿 Rails 路由的几个常用方法,支持 namespace,支持(链式)多级嵌套,支持 before_filter 和 skip_before_filter。欢迎 Pull Requests。
$ npm install railstyle-routerrequire('railstyle-router') var express = require('express') var app = express() app.configure(function() { // 设置 controller 目录的路径 app.set('controllers', __dirname + '/controllers') // 设置 controller 文件名后缀,默认为空 app.set('controller suffix', '_controller') }) app.resources('users') app.match('/login', 'sessions#new')./controllers/users_controller.js:
// GET /users exports.index = function(req, res) { console.log(req.namespace) console.log(req.controller) console.log(req.action) res.send('index') } // GET /users/new exports.new = function(req, res) { res.send('new') } // POST /users exports.create = function(req, res) { res.send('create') } // GET /users/:id exports.show = function(req, res) { res.send('show') } // GET /users/:id/edit exports.edit = function(req, res) { res.send('edit') } // PUT /users/:id exports.update = function(req, res) { res.send('update') } // DELETE /users/:id exports.destroy = function(req, res) { res.send('destroy') }默认绑定 index, show, new, edit, create, update, destroy 七个 actions。
options 支持:
path: 重写 URL 路径,不设置则默认同name一致only: 指定需要保留的 actions,可以传入数组,亦可传入以逗号分隔的字符串。如果想排除所有的 actions,请传入空数组[],而非空字符串或其他except: 排除指定的 actions,可以传入数组,亦可传入以逗号分隔的字符串
举个栗子:chestnut::
app.resources('users') GET /users.:format? users#index GET /users/:id.:format? users#show GET /users/new.:format? users#new GET /users/:id/edit.:format? users#edit POST /users.:format? users#create PUT /users/:id.:format? users#update DELETE /users/:id.:format? users#destroyapp.resources('users', { path: 'person', only: ['show', 'new', 'create'] }) GET /person/:id.:format? users#show GET /person/new.:format? users#new POST /person.:format? users#create默认绑定 show, new, edit, create, update, destroy 六个 actions。 options 同 resources。
举个:chestnut::
app.resource('users') GET /users.:format? users#show GET /users/new.:format? users#new GET /users/edit.:format? users#edit POST /users.:format? users#create PUT /users.:format? users#update DELETE /users.:format? users#destroy这两个方法用于创建非 RESTful 的路由,配合 resources 和 resource 使用:
app.resources('users', { only: [] }, function() { this.member({ get: 'profile, avatar' }) }) GET /users/:id/profile.:format? users#profile GET /users/:id/avatar.:format? users#avatarapp.resources('users', { only: [] }, function() { this.collection({ get: ['profile', 'avatar'] }) }) GET /users/profile.:format? users#profile GET /users/avatar.:format? users#avatar回调君还能协助实现嵌套路由,上:chestnut::
app.resources('users', { only: 'show' }, function() { this.resources('tweets', function() { this.resource('comments', { only: 'show' }) this.member({ post: 'balabala' }) }) }) GET /users/:id.:format? users#show GET /users/:user_id/tweets.:format? tweets#index GET /users/:user_id/tweets/:id.:format? tweets#show GET /users/:user_id/tweets/new.:format? tweets#new GET /users/:user_id/tweets/:id/edit.:format? tweets#edit POST /users/:user_id/tweets.:format? tweets#create PUT /users/:user_id/tweets/:id.:format? tweets#update DELETE /users/:user_id/tweets/:id.:format? tweets#destroy POST /users/:user_id/tweets/:id/balabala.:format? tweets#balabala GET /users/:user_id/tweets/:tweet_id/comments.:format? comments#show不喜欢回调回调再回调?试试链式的:
app.resources('users', { only: 'show' }) .resources('tweets').member({ post: 'balabala' }) .resource('comments', { only: 'show' }) GET /users/:id.:format? users#show GET /users/:user_id/tweets.:format? tweets#index GET /users/:user_id/tweets/:id.:format? tweets#show GET /users/:user_id/tweets/new.:format? tweets#new GET /users/:user_id/tweets/:id/edit.:format? tweets#edit POST /users/:user_id/tweets.:format? tweets#create PUT /users/:user_id/tweets/:id.:format? tweets#update DELETE /users/:user_id/tweets/:id.:format? tweets#destroy POST /users/:user_id/tweets/:id/balabala.:format? tweets#balabala GET /users/:user_id/tweets/:tweet_id/comments.:format? comments#show使某个 controller 下的 action 与指定的路径匹配,如果这个 action 属于 .resources() 默认 actions 的其中之一,则只会匹配相对应的 HTTP method。via 默认同时包括 get, post, put, delete 四个 HTTP methods,使用该参数可以覆盖 RESTful 规则。
app.match('/login', 'sessions#new') GET /login.:format? sessions#newapp.match('/login', 'sessions#create') POST /login.:format? sessions#createapp.match('/login', 'sessions#ooxx') GET|POST|PUT|DELETE /login.:format? sessions#ooxxapp.match('/login', 'sessions#ooxx', 'get, post') GET|POST /login.:format? sessions#ooxxapp.namespace('admin', function() { // load `./controllers/admin/users_controller.js` this.resources('users', { except: ['index', 'destroy'] }) }) GET /admin/users/:id.:format? admin/users#show GET /admin/users/new.:format? admin/users#new GET /admin/users/:id/edit.:format? admin/users#edit POST /admin/users.:format? admin/users#create PUT /admin/users/:id.:format? admin/users#update同样支持链式:
app.namespace('admin').resources('users', { except: ['index', 'destroy'] }) GET /admin/users/:id.:format? admin/users#show GET /admin/users/new.:format? admin/users#new GET /admin/users/:id/edit.:format? admin/users#edit POST /admin/users.:format? admin/users#create PUT /admin/users/:id.:format? admin/users#update在 controller 文件中加上如下代码即可。action 跟 middleware 可以一对一、一对多、多对一、多对多。星号 * 匹配所有 actions,且优先级最高。
exports.before_filter = { '*': fn1, 'create, update': fn2, 'create': [fn3, fn4], 'destroy': fn4 } function fn1(req, res, next) { //... } function fn2(req, res, next) { //... } function fn3(req, res, next) { //... } function fn4(req, res, next) { //... }星号 * 只能匹配当前 controller,想要在全部 controller 中生效,则需要使用 application[suffix].js,优先级比星号 * 更高:
module.exports = exports = function(req, res, next) { // global filter middleware } exports.other = function(req, res, next) { //... }在需要 skip 某些中间件的 controller 里:
exports.skip_before_filter = { 'new': true, // skip everything 'create, update': ['-g', fn1], // `-g` 指 `application[suffix].js` 的 `module.exports` 'destroy': [fn2, fn3] // skip 具体的中间件 }Licensed under the MIT License.