Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Remove app inheritance, encourage using multiple routers instead of mounting apps #1843

jonathanong opened this Issue · 23 comments

7 participants


See: #1637

  • Creating a new router should be easier by just doing var router = express.router()
  • Need a router.use() method to make things closer to a real app or just have people do .all() (more of a doc issue)
  • Needs updated examples and docs
  • Remove all documentation about app inheritance
tj commented

meh I think that's kinda silly personally, the apps already are really just routers


The apps are just thin config holders and some basic harnessing. Moving some of the middleware feature to routers might be nice. I dunno, I kinda got over it when the original request was denied and just stick with the supported basics for now :D


the only reason i want to do this is so we don't have to support any sort of settings inheritance. people do use apps just as routers, but then they get the unwanted side effect of the settings not being inherited. if you want to support app inheritance, that's a different thing, but IMO it's a waste of time.


this would probably be a nicer feature for people just learning about using modular apps. However, once you get there it'd probably get in the way. I don't really use many settings inside of express except the usual dev/prod stuff just my thoughts on the matter...


get in the way of what? this is just additional functionality and won't change how express works right now very much.


if I understand you correctly, you would give the idea that app. could inherit between routers, by separating it here I think you could either cause confusion or bring out the inheritance issue again... idk?


app. could inherit between routers

not sure what that means. it sounds like you think routers inherit settings from apps, which is incorrect. let me try to explain this more:

right now, people do app.use(subapp) and expect subapp to inherit settings from app. i would expect this too... except when i don't want that to happen, i.e. if the subapp is an entirely different app whose settings should not be shared.

instead of adding 100 types of options to deal with these cases, it's easier just to have people mount routers like app.use(router). now the router and all its middleware's app is app. app.use(router) is just adding more middleware. any middleware that is used by app that isn't another express instance will have app's settings.

that is, there will never be inheritance when people do app.use(subapp) or app.use(router), and we will document this specifically. i think "no inheritance, ever" is an easier concept to grasp than "there's inheritance if you do this, but no inheritance when you do that".

did that clear things up? do you have any cases (in code) that you need clarification on?


not sure what that means. it sounds like you think routers inherit settings from apps, which is incorrect.

I know that, sorry to confuse -- I meant that it could imply to someone just learning that maybe it could, or would rise the argument of having that functionality introduced, which i think we all agree against. :100:


oh, yeah. right now people will think that it could because apps do have inheritance. by explicitly documenting "there is no inheritance, ever" i think will lower the learning curve. we should also state that inheritance will never be added.

tj commented

the only thing wrong with not inheriting is for settings like "trust proxy", we'll have a similar issue in koa, pretty tempting to make that an environment variable instead of propagating settings around

tj commented

but otherwise I agree that the settings inheritance is kinda lame


I disagree that "no inheritance" is the solution. I think sub apps always should inherit.

If we do not want inheritance, we can easy to work around it. Eg.

app.use(function (req, res, next) {
  subapp(req, res, function (err) {
    req.__proto__ = app.request
    res.__proto__ = app.response

If we end up choosing to always inherit, then there should probably be a way to do the same as the code above with a fewer lines of code.


I think sub apps always should inherit.

valid opinion, but it has potential to break other people's app. it also requires more maintenance, which any maintainer is adverse to.

we can easy to work around it.

be our guest. the difference is that we won't support it.

there should probably be a way to do the same as the code above with a fewer lines of code.

exactly. var subapp = express.router(). no prototype changes necessary.

@jonathanong jonathanong was assigned

Personally; I believe router should be just another middleware.

In my use case I need multiple routers (to serve different routes based on the hostname) and having more apps would just force me to load all the same middlewares and configuration again.
The same "problem" affects the views subsystem.

I understand it's not what the majority of the users need - but someone does appreciate an extra dose of modularity :)
As of now, I'm using express.Router and a rendering engine (consolidate.dust) directly - which is kind of hackish, but it works

var router = new express.Router();

@framp In express 4 router is just another middleware


whats the difference between

app = express();
app.get('/', function(req,res,next){ req.something=true; next();});
router = express(); // this line
router.get('/', function(req,res,next){ res.send(req.something);});


app = express();
app.get('/', function(req,res,next){ req.something=true; next();});
router = app.router(); // this line
router.get('/', function(req,res,next){ res.send(req.something);});

other than

app.set('mock', 'yea');
app.set('ing', 'yea');
router = app.router();
router.set('mock', 'PLEASE STOP SINGING');
router.get('/', function(req, res, next){
    originalMock: app.get('mock')), // I would expect this to be yea still. ( don't overwrite parent get/set)
    routerMock: router.get('mock'), // PLEASE STOP SINGING
    router.get('ing'), // I would expect yea here ( inheritted from parent )

So, the only inheritance i would see would be using get/set.

I got to this thread from a search because it seemed a little odd to instanciate express again for a sub router.. then again, having a sub-method of an instance create a new child of that instance isn't really standard... what if instead of router we called it child?

of course, the existing functionality should still work, creating a router = express() and then app.use(router). I personally don't set and get a lot to the app, even though I probably should. I usually use a config handler separately.


right now that stuff is the same because there is inheritance. when we remove inheritance, the first one will break. router = express() won't have app's settings.

I personally don't set and get a lot to the app, even though I probably should. I usually use a config handler separately.

good! there are still some settings you probably need to use though like trust proxy.


So, are the view engine, etc, settings going to transfer using the current router = express(); app.use(router) method?


so... Router has no method use, or set... I would like a sub app, with app inheritance. for now, I will probably find the getter/setter attributes storage and deep extend that onto the newly created express() app.

Here's what should be possible

parentApp = express();

parentApp.set('views', join(__dirname, 'views'));
parentApp.set('view engine', 'ect');
parentApp.engine('ect', ectRenderer.render);

parentApp.use('/', function(req, res, next){ res.send('Hey, index'); });
parentApp.use('/childSection', require('./child_section')(parentApp));

// In childSection/index.js
module.exports = function(parentApp){
  childApp = parentApp.child();
  childApp.get('/', function(req, res, next){

I'd rather not duplicate

parentApp.set('views', join(__dirname));
parentApp.set('view engine', 'ect');
parentApp.engine('ect', ectRenderer.render);

within childSection/index.js.

I'm probably going to build my own extender for this purpose, but it would be nice if we could treat express apps as instances of classes, which can be extended like any other class. I surely am not going to set my views up repeatedly

For these purposes

I've hacked in

_.extend(subApp.settings, app.settings);
_.extend(subApp.engines, app.engines);

It seems to do what I was looking for, which is not duplicate view engine settings.

My view directory is not /views, it is top


This way, i call res.render('views/index'), and <% include 'views/layout' %>. I always assume this structure, so even within my module1/views/index, I can still call <% include 'views/layout' %>.


Right now I am leaning towards making app.use(another_app) just mount the internal router of the other app. This means that the second apps settings or other things are ignored (which is consistent with current behavior) or was the intent of this change to allow the other app to preserve its settings?


Personally I'm okay with that, but someone might complain that there's no possibility for encapsulation.


I am leading app handling/mounting another app as it. This provides a way for users to isolate views or whatever into apps if they want. For users who want the same view system/single app I will be updating the website/docs with a new "routing" section that outlines how to better leverage the more powerful Router in express 4

@jonathanong jonathanong removed their assignment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.