The Right Code

Home of Greg Bergé. Let's speak about JavaScript.

Sub-applications: differences between express 3.x and express 4.x

If you know node, you probably know express. Express was originally coded by TJ Holowaychuk, one of the most active developer in the node.js community. Express is now the most common framework to make an http server in node.js.

A good practice in express is to separate each application domain in small applications that can be mounted on a specific path.

Express 3.x: sub-applications

Let's take an app that contains a website and an API.

var express = require('express');

// Main application.
var app = express();

// Website application.
var website = express();  
website.get('/', function (req, res) {  
  res.send('hello');
});

// API application.
var api = express();  
api.get('/articles', function (req, res) {  
  res.send([{ title: 'hello' }]);
});

// Mouting applications.
app.use('/', website);  
app.use('/api', api);

// Start listening.
app.listen(3000);  

Ok, we have now one big application with two small sub-applications. It works.

Now we want to add views in our application, so we configure it with "my-views" as views path.

app.set('view engine', 'html');  
app.set('views', require('path').join(__dirname, 'my-views'));  
app.engine('html', require('ejs').renderFile);  

We modify the home of the website to render the home view.

website.get('/', function (req, res) {  
  res.render('home');
});

And now we run the app, and there is an error:

Error: Failed to lookup view "home" in views directory "~/express-test/views"  

Ho? Stop? I have setted my view path to "my-views" and you search my view in "views". What the fuck!?

The reponse is very simple:

Express 3.x doesn't completely support settings inheritance.

The setting "views" wasn't propagated to the sub-application "website". Unfortunately, I don't have good solution for that, it's just a lame. But hopefully express 4 is coming!

Express 4.x: routers

Express 4.x introduce a new feature: the routers. Routers are just like sub-application except that they don't create a completely new app and inherits their settings from the main application. It's truely just a middleware.

So let's adapt our example to express 4.x.

var express = require('express');

// Main application.
var app = express();  
app.set('view engine', 'html');  
app.set('views', require('path').join(__dirname, 'my-views'));  
app.engine('html', require('ejs').renderFile);

// Website application.
var website = new express.Router();  
website.get('/', function (req, res) {  
  res.render('home');
});

// API application.
var api = new express.Router();  
api.get('/articles', function (req, res) {  
  res.send([{ title: 'hello' }]);
});

// Mouting applications.
app.use('/', website);  
app.use('/api', api);

// Start listening.
app.listen(3000);  

We have just replaced express() by new express.Router() and now it works! Aleluia!

Conclusion

The main difference between sub-applications and routers are the settings inheritance.

Express 4 introduce the router, so you can now modularize your applications without complicate things with problems of settings inheritance.

You can create a sub-application in express if you want and especially if you need two completely separated applications without settings inheritance.

comments powered by Disqus