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());
This commit is contained in:
Roman Shtylman
2014-02-26 19:57:11 -05:00
parent caa25b506d
commit f8b954bcd9
3 changed files with 52 additions and 26 deletions

View File

@@ -9,31 +9,32 @@ var Route = require('./route')
, debug = require('debug')('express:router')
, parseUrl = utils.parseUrl;
/**
* Expose `Router` constructor.
*/
exports = module.exports = Router;
/**
* Initialize a new `Router` with the given `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 || {};
var self = this;
self.params = {};
self._params = [];
self.caseSensitive = options.caseSensitive;
self.strict = options.strict;
self.stack = [];
function router(req, res, next) {
router.handle(req, res, next);
};
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.
@@ -69,7 +70,7 @@ function Router(options) {
* @api public
*/
Router.prototype.param = function(name, fn){
proto.param = function(name, fn){
// param logic
if ('function' == typeof name) {
this._params.push(name);
@@ -107,7 +108,7 @@ Router.prototype.param = function(name, fn){
* @api private
*/
Router.prototype.handle = function(req, res, done) {
proto.handle = function(req, res, done) {
var self = this;
debug('dispatching %s %s', req.method, req.url);
@@ -127,7 +128,7 @@ Router.prototype.handle = function(req, res, done) {
var options = [];
// middleware and routes
var stack = this.stack;
var stack = self.stack;
// for options requests, respond with a default if nothing else responds
if (method === 'options') {
@@ -242,7 +243,7 @@ Router.prototype.handle = function(req, res, done) {
* @api private
*/
Router.prototype.process_params = function(route, req, res, done) {
proto.process_params = function(route, req, res, done) {
var self = this;
var params = this.params;
@@ -317,7 +318,7 @@ Router.prototype.process_params = function(route, req, res, done) {
* @api public
*/
Router.prototype.use = function(route, fn){
proto.use = function(route, fn){
// default route to '/'
if ('string' != typeof route) {
@@ -356,7 +357,7 @@ Router.prototype.use = function(route, fn){
* @api public
*/
Router.prototype.route = function(path){
proto.route = function(path){
var route = new Route(path);
var layer = Layer(path, {
@@ -381,7 +382,7 @@ Router.prototype.route = function(path){
* @api public
*/
Router.prototype.all = function(path, fn) {
proto.all = function(path, fn) {
var route = this.route(path);
methods.forEach(function(method){
route[method](fn);
@@ -390,9 +391,10 @@ Router.prototype.all = function(path, fn) {
// create Router#VERB functions
methods.forEach(function(method){
Router.prototype[method] = function(path, fn){
proto[method] = function(path, fn){
var self = this;
self.route(path)[method](fn);
return self;
};
});

View File

@@ -6,7 +6,31 @@ var express = require('../')
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){
var router = new Router();

View File

@@ -31,7 +31,7 @@ describe('OPTIONS', function(){
var router = new express.Router();
router.get('/users', function(req, res){});
app.use(router.middleware);
app.use(router);
app.get('/other', function(req, res){});
request(app)