Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to export all routes in Express?

I have an NodeJS Express app that is getting really big in just one file (app.js).

I want to export all my routes into a single, external file, say ./lib/routes.js. How to do that?

How to export the following bit of code and require it correctly in main app.js?

app.get('/logout', function(req, res) {
    res.render('logout', {
        username: req.session.username
    });
});

app.get('/dashboard', function(req, res) {
    res.render('dashboard', {
        username: req.session.username
    });
});

app.get('/login', function(req, res) {
    res.render('login', {
        badLogin: false,
        loginError: false
    });
});
like image 686
Pono Avatar asked May 26 '11 14:05

Pono


3 Answers

What I do is group my routes by controller. For each group of related routes (users, shopping cart, whatever), I make a controller file that lives in app/controllers/foo.js where foo is the controller name. In my main javascript server file (where all your code currently lives), I require each controller by name and then call its setup function, passing in my express app object, and allow the controller to add whatever routes it needs.

['api', 'authorization', 'users', 'tests'].map(function(controllerName) {
    var controller = require('./controllers/' + controllerName);
    controller.setup(app);
 });

Inside each controller, I do something like:

exports.setup = function(app) {
    app.get('/dashboard', function(req, res) {
        res.render('dashboard', {
            username: req.session.username
        });
    });
};
like image 186
Peter Lyons Avatar answered Oct 22 '22 12:10

Peter Lyons


Why not do something like this:

// logout.js
module.exports = function(req, res){
  res.render('logout', {
    username: req.session.username
  });
});

// dashboard.js
module.exports = function(req, res){
  res.render('dashboard', {
    username: req.session.username
  });
});

// login.js
module.exports = function(req, res){
  res.render('login', {
    badLogin: false,
    loginError: false
  });
});

// app.js
app.get('/logout', require('logout'));
app.get('/dashboard', require('dashboard'));
app.get('/login', require('login'));

Also, you could imagine easily using http://nodejs.org/docs/v0.4.8/api/fs.html#fs.readdir to loop through a routes directory and load these up programmatically.

You could even do something along the lines of...

module.exports.handler[] = {
    method : 'get',
    route  : '/login',
    action : res.render('login', {
       badLogin: false,
       loginError: false
    });
}

Though I think I'd spend a little time thinking about how to simplify that.

like image 37
Josh Avatar answered Oct 22 '22 11:10

Josh


using glob you can export all routes on directory for example '/routes':

npm i --save glob


    // *** /routes/index.js file ***

    const express = require('express')
    const Router = express.Router
    const router = Router()
    const glob = require('glob')


    /**
     * options ignore files inside routes folder
     */
    const options = {
        ignore: [`${__dirname}/_helpers.js`, `${__dirname}/index.js`]
    }

    /**
     * read all files on current directory and export routes as lowercase of the filename
     * example 'routes/Products.js' route will be access by '/products'
     */
    const routes = 
        glob.sync(__dirname + '/*.js', options)
            .map(filename => {
                const arr = filename.split('/')
                let name = arr.pop();
                name = name.replace('.js', '')
                return {
                    path: `/${name.toLowerCase()}`,
                    router: require(`${filename.replace('.js', '')}`)
                }
            })
            .filter(obj => Object.getPrototypeOf(obj.router) == Router)
            .forEach(obj => router.use(obj.path, obj.router))


    module.exports = router;

then

on app.js

// app.js file

const express = require('express')
const routes = require('./routes')


const app = express()

app.use('/api', routes)

like image 40
Guille Anselmi Avatar answered Oct 22 '22 11:10

Guille Anselmi