Skip to content

Instantly share code, notes, and snippets.

@coiscir
Created December 10, 2012 02:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coiscir/4248054 to your computer and use it in GitHub Desktop.
Save coiscir/4248054 to your computer and use it in GitHub Desktop.
Express Routing

An idea for defining routes for Express applications in Objects of paths, (optional) verbs, then handlers:

var express = require('express');
var routing = require('./routing');
var app = express();

routing(app, {
  // `get` only
  '/': function (req, res) {
    res.render('index');
  },

  '/contact': {
    get: function (req, res) {
      res.render('contact');
    },

    post: function (req, res) {
      // ...
    }
  }
});

They can also be defined and found in modules under a basedir via glob. This does assume the basedir is dedicated to such modules, however:

// ...
routing(app, __dirname + '/routes');
// ./routes/index.js
module.exports = {
  '/': function (req, res) {
    res.render('index');
  }
};
// ./routes/contact.js
module.exports = {
  '/contact': {
    get: function (req, res) {
      res.render('contact');
    },

    post: function (req, res) {
      // ...
    }
  }
};

Modules are sorted by their dirname, then by their basename with priority given to index.js.

{
"name": "express-routing",
"version": "0.0.0",
"private": true,
"author": "Jonathan Lonowski <coiscir@gmail.com>",
"license": "MIT",
"main": "./routing",
"dependencies": {
"glob": "latest"
}
}
var glob = require('glob');
var path = require('path');
function compare(a, b) {
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
}
function attach(app, router) {
Object.keys(router).forEach(function (route) {
var desc = router[route];
if (typeof desc === 'function' || Array.isArray(desc)) {
desc = { get: desc };
}
Object.keys(desc).forEach(function (verb) {
app[verb](route, desc[verb]);
});
});
}
function search(app, basedir) {
var stats = {};
function statify(filepath) {
return {
dirname: path.dirname(filepath),
basename: path.basename(filepath)
};
}
var modules = glob.sync(path.join(basedir, '**', '*.js')).map(path.normalize)
.sort(function (af, bf) {
var a = stats[af];
var b = stats[bf];
if (a == null) a = stats[af] = statify(af);
if (b == null) b = stats[bf] = statify(bf);
return (
compare(a.dirname, b.dirname) ||
compare(a.basename !== 'index.js', b.basename !== 'index.js') ||
compare(a.basename, b.basename)
);
});
modules.forEach(function (file) {
attach(app, require(path.resolve(__dirname, file)));
});
}
function inspect(app, routes) {
if (routes == null) {
return;
} else if (Array.isArray(routes)) {
routes.forEach(function (item) {
inspect(app, item);
});
} else if (typeof routes === 'string') {
search(app, routes);
} else {
attach(app, routes);
}
}
module.exports = inspect;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment