Nodejs Rails-like routing for Express 3.x

Nodejs Rails-like routing for Express 3.x

高仿 Rails 路由的几个常用方法,支持 namespace,支持(链式)多级嵌套,支持 before_filter。欢迎 Pull Requests。

Installation

$ npm install railstyle-router

Usage

var express = require('express')
require('railstyle-router')

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')
}

APIs

.resources(name, [options])

默认绑定 index, show, new, edit, create, update, destroy 七个 actions。

options 支持:

  • path: 重写 URL 路径,不设置则默认同 name 一致
  • only: 指定需要的 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#destroy

app.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

.resource(name, [options])

默认绑定 show, new, edit, create, update, destroy 六个 actions。 optionsresources

举个: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

.member(routes) / .collection(routes)

这两个方法用于创建非 RESTful 的路由,配合 resourcesresource 使用:

app.resources('users', { only: [] }, function() {
  this.member({
    get: 'profile, avatar'
  })
})

GET /users/:id/profile.:format? users#profile GET /users/:id/avatar.:format? users#avatar

app.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

.match(path, [namespace/]controller#action)

使某个 controller 下的 action 与指定的路径匹配,同时兼容 get, post, put, delete 四个 HTTP verbs。

app.match('/login', 'sessions#new')

GET|POST|PUT|DELETE /login.:format? sessions#new

.namespace(path, callback)

app.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

before_filter

在 controller 文件中加上如下代码即可。星号 * 匹配所有 actions,且优先级最高。

exports.before_filter = {
  '*': auth,
  create: admin,
  destroy: [admin, master]
}

function auth(req, res, next) { // … next() } function admin(req, res, next) { // … next() } function master(req, res, next) { // … next() }

License

Licensed under the MIT License.


5 回复

Node.js Rails-like Routing for Express 3.x

本篇文档介绍如何在Express 3.x中使用类似于Ruby on Rails的路由系统。通过使用railstyle-router库,你可以实现资源路由、命名空间、嵌套路由以及过滤器等功能。

安装

首先,你需要安装railstyle-router库:

$ npm install railstyle-router

使用

接下来,我们来看一下如何在Express应用中使用这个库。

var express = require('express');
require('railstyle-router');

var app = express();

app.configure(function() {
  // 设置控制器目录路径
  app.set('controllers', __dirname + '/controllers');
  // 设置控制器文件名后缀,默认为空
  app.set('controller suffix', '_controller');
});

// 定义资源路由
app.resources('users');
// 定义自定义路由
app.match('/login', 'sessions#new');

示例控制器

假设你有一个名为users_controller.js的控制器文件,其内容如下:

// GET /users
exports.index = function(req, res) {
  console.log(req.namespace); // 输出:undefined
  console.log(req.controller); // 输出:users
  console.log(req.action);     // 输出:index

  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');
};

API 详解

.resources(name, [options])

此方法用于定义资源路由,支持index, show, new, edit, create, update, destroy等七个操作。

app.resources('users', {
  path: 'person',
  only: ['show', 'new', 'create']
});
.resource(name, [options])

此方法用于定义单个资源路由,只支持show, new, edit, create, update, destroy六个操作。

app.resource('users');
.member(routes) / .collection(routes)

这两个方法用于定义非RESTful路由,可以与resourcesresource一起使用。

app.resources('users', { only: [] }, function() {
  this.member({
    get: 'profile, avatar'
  });
});
.match(path, [namespace/]controller#action)

此方法用于匹配特定路径到某个控制器的操作。

app.match('/login', 'sessions#new');
.namespace(path, callback)

此方法用于定义命名空间路由。

app.namespace('admin', function() {
  this.resources('users', { except: ['index', 'destroy'] });
});
before_filter

在控制器文件中添加以下代码以实现过滤器功能。

exports.before_filter = {
  '*': auth,
  create: admin,
  destroy: [admin, master]
};

function auth(req, res, next) {
  // ...
  next();
}

function admin(req, res, next) {
  // ...
  next();
}

function master(req, res, next) {
  // ...
  next();
}

通过以上步骤,你可以实现一个类似于Ruby on Rails的路由系统,从而更方便地管理你的Express应用中的路由。


cool ps:LZ的octopress主题也很漂亮

楼主现在都不写代码了。

image.png 楼上诽谤

为了实现类似于 Rails 路由的 Node.js Express 3.x 应用程序,我们可以使用 railstyle-router 这个库来简化路由配置。下面将详细解释如何安装和使用这个库,并提供一些示例代码。

安装

首先,确保你的项目已经初始化并且安装了 npm。然后运行以下命令来安装 railstyle-router

$ npm install railstyle-router

使用

接下来,我们可以在应用中引入 railstyle-router 并配置路由。

示例代码

  1. 设置控制器目录和文件后缀

    var express = require('express');
    require('railstyle-router');
    
    var app = express();
    
    app.configure(function() {
      // 设置控制器目录路径
      app.set('controllers', __dirname + '/controllers');
      // 设置控制器文件名后缀,默认为空
      app.set('controller suffix', '_controller');
    });
    
  2. 定义资源路由

    app.resources('users');
    app.match('/login', 'sessions#new');
    
  3. 定义控制器文件

    controllers/users_controller.js 中:

    exports.index = function(req, res) {
      res.send('index');
    };
    
    exports.new = function(req, res) {
      res.send('new');
    };
    
    exports.create = function(req, res) {
      res.send('create');
    };
    
    exports.show = function(req, res) {
      res.send('show');
    };
    
    exports.edit = function(req, res) {
      res.send('edit');
    };
    
    exports.update = function(req, res) {
      res.send('update');
    };
    
    exports.destroy = function(req, res) {
      res.send('destroy');
    };
    
  4. 定义命名空间

    app.namespace('admin', function() {
      this.resources('users', { except: ['index', 'destroy'] });
    });
    
    // 或者使用链式
    app.namespace('admin').resources('users', { except: ['index', 'destroy'] });
    
  5. 添加 before_filter

    在控制器中添加过滤器:

    exports.before_filter = {
      '*': auth,
      create: admin,
      destroy: [admin, master]
    };
    
    function auth(req, res, next) {
      // 执行认证逻辑
      next();
    }
    
    function admin(req, res, next) {
      // 执行管理员逻辑
      next();
    }
    
    function master(req, res, next) {
      // 执行超级管理员逻辑
      next();
    }
    

通过以上步骤,你可以实现类似 Rails 路由功能的 Node.js Express 3.x 应用程序。

回到顶部