make express.Router() return a Router function instance

Similar to how express() returns an express `app` instance which is also
a function, express.Router() returns the Router instance which is also a
function and can be easily used via another router or the app.

app.use(express.Router());
Esse commit está contido em:
Roman Shtylman
2014-02-26 19:57:11 -05:00
commit f8b954bcd9
3 arquivos alterados com 52 adições e 26 exclusões
+26 -24
Ver Arquivo
@@ -9,31 +9,32 @@ var Route = require('./route')
, debug = require('debug')('express:router') , debug = require('debug')('express:router')
, parseUrl = utils.parseUrl; , parseUrl = utils.parseUrl;
/**
* Expose `Router` constructor.
*/
exports = module.exports = Router;
/** /**
* Initialize a new `Router` with the given `options`. * Initialize a new `Router` with the given `options`.
* *
* @param {Object} options * @param {Object} options
* @api private * @return {Router} which is an callable function
* @api public
*/ */
function Router(options) { var proto = module.exports = function(options) {
options = options || {}; options = options || {};
var self = this;
self.params = {}; function router(req, res, next) {
self._params = []; router.handle(req, res, next);
self.caseSensitive = options.caseSensitive; };
self.strict = options.strict;
self.stack = [];
self.middleware = self.handle.bind(self); // mixin Router class functions
} router.__proto__ = proto;
router.params = {};
router._params = [];
router.caseSensitive = options.caseSensitive;
router.strict = options.strict;
router.stack = [];
return router;
};
/** /**
* Map the given param placeholder `name`(s) to the given callback. * Map the given param placeholder `name`(s) to the given callback.
@@ -69,7 +70,7 @@ function Router(options) {
* @api public * @api public
*/ */
Router.prototype.param = function(name, fn){ proto.param = function(name, fn){
// param logic // param logic
if ('function' == typeof name) { if ('function' == typeof name) {
this._params.push(name); this._params.push(name);
@@ -107,7 +108,7 @@ Router.prototype.param = function(name, fn){
* @api private * @api private
*/ */
Router.prototype.handle = function(req, res, done) { proto.handle = function(req, res, done) {
var self = this; var self = this;
debug('dispatching %s %s', req.method, req.url); debug('dispatching %s %s', req.method, req.url);
@@ -127,7 +128,7 @@ Router.prototype.handle = function(req, res, done) {
var options = []; var options = [];
// middleware and routes // middleware and routes
var stack = this.stack; var stack = self.stack;
// for options requests, respond with a default if nothing else responds // for options requests, respond with a default if nothing else responds
if (method === 'options') { if (method === 'options') {
@@ -242,7 +243,7 @@ Router.prototype.handle = function(req, res, done) {
* @api private * @api private
*/ */
Router.prototype.process_params = function(route, req, res, done) { proto.process_params = function(route, req, res, done) {
var self = this; var self = this;
var params = this.params; var params = this.params;
@@ -317,7 +318,7 @@ Router.prototype.process_params = function(route, req, res, done) {
* @api public * @api public
*/ */
Router.prototype.use = function(route, fn){ proto.use = function(route, fn){
// default route to '/' // default route to '/'
if ('string' != typeof route) { if ('string' != typeof route) {
@@ -356,7 +357,7 @@ Router.prototype.use = function(route, fn){
* @api public * @api public
*/ */
Router.prototype.route = function(path){ proto.route = function(path){
var route = new Route(path); var route = new Route(path);
var layer = Layer(path, { var layer = Layer(path, {
@@ -381,7 +382,7 @@ Router.prototype.route = function(path){
* @api public * @api public
*/ */
Router.prototype.all = function(path, fn) { proto.all = function(path, fn) {
var route = this.route(path); var route = this.route(path);
methods.forEach(function(method){ methods.forEach(function(method){
route[method](fn); route[method](fn);
@@ -390,9 +391,10 @@ Router.prototype.all = function(path, fn) {
// create Router#VERB functions // create Router#VERB functions
methods.forEach(function(method){ methods.forEach(function(method){
Router.prototype[method] = function(path, fn){ proto[method] = function(path, fn){
var self = this; var self = this;
self.route(path)[method](fn); self.route(path)[method](fn);
return self; return self;
}; };
}); });
+25 -1
Ver Arquivo
@@ -6,7 +6,31 @@ var express = require('../')
describe('Router', function(){ describe('Router', function(){
describe('.middleware', function(){ it('should return a function with router methods', function() {
var router = Router();
assert(typeof router == 'function');
var router = new Router();
assert(typeof router == 'function');
assert(typeof router.get == 'function');
assert(typeof router.handle == 'function');
assert(typeof router.use == 'function');
});
it('should support .use of other routers', function(done) {
var router = Router();
var another = Router();
another.get('/bar', function(req, res) {
res.done();
});
router.use('/foo', another);
router.handle({ url: '/foo/bar', method: 'GET' }, { done: done });
});
describe('.handle', function(){
it('should dispatch', function(done){ it('should dispatch', function(done){
var router = new Router(); var router = new Router();
+1 -1
Ver Arquivo
@@ -31,7 +31,7 @@ describe('OPTIONS', function(){
var router = new express.Router(); var router = new express.Router();
router.get('/users', function(req, res){}); router.get('/users', function(req, res){});
app.use(router.middleware); app.use(router);
app.get('/other', function(req, res){}); app.get('/other', function(req, res){});
request(app) request(app)