Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added dynamic URL recognition in the Router

  • Loading branch information...
commit 70641290cf17596cd9b86ca760611b92d27fbb48 1 parent 9bf69ad
David Coallier authored
Showing with 84 additions and 15 deletions.
  1. +4 −4 README.md
  2. +77 −8 lib/restlike.js
  3. +3 −3 server.js
View
8 README.md
@@ -18,13 +18,13 @@ synopsis
var restlike = require('./lib/restlike');
- http.creatServer(function (request, response) {
+ http.createServer(function (request, response) {
var restlike = new restlike.Restlike(request, response);
- restlike.match('/my/road', {
+ restlike.match('/my/:name', {
// Handle the GET request
- get: function() {
- return {"name": "fun"};
+ get: function(data) {
+ return {"name": data.name};
},
// Handle the POST request
View
85 lib/restlike.js
@@ -9,22 +9,88 @@
* Date: 28th September, 2010
*/
var url = require('url');
+var sys = require('sys');
/**
* The router that matches routes
*/
var Router = function(){};
-Router.prototype.match = function (activeRoute, expectedRoute) {
- if (activeRoute == expectedRoute) {
- return true;
+
+/**
+ * This method is used to normalise URLs.
+ *
+ * This method receives an active route and normalises it. We have something
+ * very similar in the FRAPI router that we split all the /: and identify
+ * the keys in the URL. We then populate the keys array with the keys
+ * and return whatever has been matched.
+ *
+ * This method was taken from middleware-connect:
+ * @link https://github.com/senchalabs/connect/blob/master/lib/connect/middleware/router.js
+ *
+ * @param {String} The path to normalise and retrieve the parameters from.
+ * @param {Array} An array of keys retrieved from the routes.
+ * @return {Object} A RegExp object ready to be "exec"ed
+*/
+
+Router.prototype.normalisePath = function (path, keys) {
+ path = path.concat('/?').replace(/\/\(/g, '(?:/')
+ .replace(/(\/)?(\.)?:(\w+)(\?)?/g, function(m, slash, format, key, optional) {
+ keys.push(key);
+ return ''
+ + (optional ? '' : slash || '') + '(?:'
+ + (format || '') + '([^/.]+))';
+ })
+ .replace(/([\/.])/g, '\\$1')
+ .replace(/\*/g, '(.+)');
+ return new RegExp('^' + path + '$', 'i');
+}
+
+/**
+ * This method matches the urls.
+ *
+ * This method superceeds the previous "match" methdo that was matchin
+ * only the static routes.
+ *
+ * With this method, we are able to identify URIs as such as /name/:key and
+ * return the {'key': 'value'}.
+ *
+ * In the event where nothing has been identified, we verify if the two urls
+ * are the same and if they are, we return true. If the return value is an empty
+ * object '{}' we return false.
+ *
+ * @param {String} The active route to match.
+ * @param {String} The expected route that should look like the activeroute
+ * or at least match once normalised.
+ *
+ * @return {Mixed} Either a boolean true if the url is the exact same one (static),
+ * either a false if nothing has been matched, or an object of key-value
+ * of dynamic parameters identified by the Router.
+ */
+Router.prototype.matchDynamic = function (activeRoute, expectedRoute) {
+ var keys = [];
+ var path = this.normalisePath(activeRoute, keys);
+
+ var retValue = {};
+
+ if (matched = path.exec(expectedRoute)) {
+ for (var i = 1; i < matched.length; i++) {
+ if (typeof matched[i] === 'string') {
+ retValue[keys[i-1]] = matched[i];
+ }
+ }
+ } else {
+ if (activeRoute == expectedRoute) {
+ return true;
+ }
}
- return false;
+ return JSON.stringify(retValue) == '{}' ? false : retValue;
};
/**
* This is where the content negotiation and what kind of
- * response is returned to the users
+ * response is returned to the users.
+ *
* @param {Object} An object of the HTTP Request from require('http') containing
* the request information.
*
@@ -151,8 +217,11 @@ Restlike.prototype.match = function(route, callback) {
var response = {};
var httpMethod = this.request.method.toLowerCase();
- if (router.match(route, this.request.url)) {
- var caller = eval('callback.'+httpMethod);
+ if (matchedRoute = router.matchDynamic(route, this.request.url)) {
+ var caller = function() {
+ return callback[httpMethod](matchedRoute);
+ };
+
response = content.negotiate(caller(url.parse(this.request.url, true).query));
if (response.headers) {
this.response.writeHead(response.statusCode, response.headers);
@@ -164,4 +233,4 @@ Restlike.prototype.match = function(route, callback) {
};
// The node.js exports
-exports.Restlike = Restlike;
+exports.Restlike = Restlike;
View
6 server.js
@@ -4,9 +4,9 @@ var restlike = require('./lib/restlike');
http.createServer(function (request, response) {
var rest = new restlike.Restlike(request, response);
- rest.match('/time/to/go', {
- get: function() {
- return [1,2,3];
+ rest.match('/who/:are/you/:really', {
+ get: function(data) {
+ return data;
}
});
Please sign in to comment.
Something went wrong with that request. Please try again.