Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express: How to pass app-instance to routes from a different file?

I want to split up my routes into different files, where one file contains all routes and the other one the corresponding actions. I currently have a solution to achieve this, however I need to make the app-instance global to be able to access it in the actions. My current setup looks like this:

app.js:

var express   = require('express'); var app       = express.createServer(); var routes    = require('./routes');  var controllers = require('./controllers'); routes.setup(app, controllers);  app.listen(3000, function() {   console.log('Application is listening on port 3000'); }); 

routes.js:

exports.setup = function(app, controllers) {    app.get('/', controllers.index);   app.get('/posts', controllers.posts.index);   app.get('/posts/:post', controllers.posts.show);   // etc.  }; 

controllers/index.js:

exports.posts = require('./posts');  exports.index = function(req, res) {   // code }; 

controllers/posts.js:

exports.index = function(req, res) {   // code };  exports.show = function(req, res) {   // code }; 

However, this setup has a big issue: I have a database- and an app-instance I need to pass to the actions (controllers/*.js). The only option I could think of, is making both variables global which isn't really a solution. I want to separate routes from the actions because I have a lot of routes and want them in a central place.

What's the best way to pass variables to the actions but separate the actions from the routes?

like image 491
Claudio Albertin Avatar asked Apr 10 '12 14:04

Claudio Albertin


People also ask

How can we create Chainable route handlers for a route path in Expressjs app?

By using app. route() method, we can create chainable route handlers for a route path in Express.

How do you create routes in an Express application?

To use the router module in our main app file we first require() the route module (wiki. js). We then call use() on the Express application to add the Router to the middleware handling path, specifying a URL path of 'wiki'.


2 Answers

Use req.app, req.app.get('somekey')

The application variable created by calling express() is set on the request and response objects.

See: https://github.com/visionmedia/express/blob/76147c78a15904d4e4e469095a29d1bec9775ab6/lib/express.js#L34-L35

like image 87
Feng Avatar answered Sep 23 '22 11:09

Feng


Node.js supports circular dependencies.
Making use of circular dependencies instead of require('./routes')(app) cleans up a lot of code and makes each module less interdependent on its loading file:


app.js
var app = module.exports = express(); //now app.js can be required to bring app into any file  //some app/middleware setup, etc, including  app.use(app.router);  require('./routes'); //module.exports must be defined before this line 


routes/index.js
var app = require('../app');  app.get('/', function(req, res, next) {   res.render('index'); });  //require in some other route files...each of which requires app independently require('./user'); require('./blog'); 


-----04/2014 update-----
Express 4.0 fixed the usecase for defining routes by adding an express.router() method!
documentation - http://expressjs.com/4x/api.html#router

Example from their new generator:
Writing the route:
https://github.com/expressjs/generator/blob/master/templates/js/routes/index.js
Adding/namespacing it to the app: https://github.com/expressjs/generator/blob/master/templates/js/app.js#L24

There are still usecases for accessing app from other resources, so circular dependencies are still a valid solution.

like image 27
Will Stern Avatar answered Sep 22 '22 11:09

Will Stern