Skip to content

Instantly share code, notes, and snippets.

@zbabtkis
Last active December 23, 2015 09:19
Show Gist options
  • Save zbabtkis/6613539 to your computer and use it in GitHub Desktop.
Save zbabtkis/6613539 to your computer and use it in GitHub Desktop.
Super simple router for node js applications. Can handle file requests as well as clean url paths. Instantiate the Router object by passing the following in as a single object argument. ``` { basePath: '../public/', routes: { '/': function(req, res) { req.url = 'index.html'; this.route(req, res); } } ``` You can define more routes later using th…
var fs = require('fs')
, Router;
/**
* Router Constructor
*
* Sets default router values and provides file serving functionality.
*
* @param {Object} options Used to set basePath and default GET routes for Router.
*/
Router = function (options) {
this.GET = {};
this.POST = {};
this.PUT = {};
this.DELETE = {};
this.OPTIONS = {};
this.GET.default = function (req, res) {
req.url = req.url.split('?')[0];
if( req.method !== 'GET' ) return this.fail();
fs.readFile( options.basePath + req.url.replace(/^\/+/, ''), function(err, data) {
if(err) {
this.fail(req, res);
return false;
}
res.writeHead(200);
res.end(data);
return true;
}.bind( this ));
};
for(var route in options.routes) {
this.get(route, options.routes[route]);
}
};
/**
* Build regular expression out of clean URL syntax to match routes
*
* @param {String} route Clean url.
* @return {Object} containing RegEx route and ordered parameter keys.
*/
Router.buildRegEx = function(route) {
return {
route: '^' + route.replace(/(:([^\/]+))/g, '([^\/]+)') + '$',
params: route.match(/:([^\/]+)/g)
};
}
/**
* Routes request to correct callback.
*
* @param {Object} req Request values.
* @param {Object} res Used to respond to client.
*
* @return router instance.
*/
Router.prototype.route = function (req, res) {
var action, match, rt;
req.params = {};
for( var route in this[req.method] ) {
if( (match = req.url.match(route)) !== null ) {
for(var i = 1; i < match.length; i++) {
rt = this[req.method][route];
// Remove : from param key and set param value to match.
req.params[rt.params[i-1].substr(1)] = match[i];
}
action = this[req.method][route].callback;
}
}
if( typeof action === 'undefined' && this.GET.default ) {
action = this.GET.default;
} else if( typeof action === 'undefined' ) {
action = this.fail
}
action.call(this, req, res);
return this;
};
/**
* A helper method to serve out 404s.
*
* @param {Object} req Client request.
* @param {Object} res Response to client.
*
* @return router instance.
*/
Router.prototype.fail = function (req, res) {
res.setHeader( "Content-Type", "text/html" );
res.statusCode = 404;
res.end( "<h1>404: File Not Found</h1>" );
return this;
};
/**
* Create new GET route with callback.
*
* @param {String} route Clean URL style route string.
* @param {Function} callback Callback function to run when path is matched.
*
* @return router instance
*/
Router.prototype.get = function (route, callback) {
var route = Router.buildRegEx(route);
this.GET[route.route] = {
callback: callback,
params: route.params
};
return this;
}
Router.prototype.post = function (route, callback) {
var route = Router.buildRegEx(route);
this.POST[route.route] = {
callback: callback,
params: route.params
};
return this;
}
Router.prototype.put = function (route, callback) {
var route = Router.buildRegEx(route);
this.PUT[route.route] = {
callback: callback,
params: route.params
};
return this;
}
Router.prototype.delete = function (route, callback) {
var route = Router.buildRegEx(route);
this.DELETE[route.route] = {
callback: callback,
params: route.params
};
return this;
}
Router.prototype.options = function (route, callback) {
var route = Router.buildRegEx(route);
this.OPTIONS[route.route] = {
callback: callback,
params: route.params
};
return this;
}
module.exports = Router;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment