Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added dynamic URL recognition in the Router

  • Loading branch information...
commit 70641290cf17596cd9b86ca760611b92d27fbb48 1 parent 9bf69ad
authored November 12, 2010
8  README.md
Source Rendered
@@ -18,13 +18,13 @@ synopsis
18 18
 
19 19
     var restlike = require('./lib/restlike');
20 20
 
21  
-    http.creatServer(function (request, response) {
  21
+    http.createServer(function (request, response) {
22 22
         var restlike = new restlike.Restlike(request, response);
23 23
     
24  
-        restlike.match('/my/road', {
  24
+        restlike.match('/my/:name', {
25 25
             // Handle the GET request
26  
-            get: function() { 
27  
-                return {"name": "fun"};
  26
+            get: function(data) { 
  27
+                return {"name": data.name};
28 28
             },
29 29
             
30 30
             // Handle the POST request
85  lib/restlike.js
@@ -9,22 +9,88 @@
9 9
  * Date: 28th September, 2010
10 10
  */
11 11
 var url = require('url');
  12
+var sys = require('sys');
12 13
 
13 14
 /**
14 15
  * The router that matches routes
15 16
  */
16 17
 var Router = function(){};
17  
-Router.prototype.match = function (activeRoute, expectedRoute) {
18  
-    if (activeRoute == expectedRoute) {
19  
-        return true;
  18
+
  19
+/**
  20
+ * This method is used to normalise URLs.
  21
+ *
  22
+ * This method receives an active route and normalises it. We have something
  23
+ * very similar in the FRAPI router that we split all the /: and identify
  24
+ * the keys in the URL. We then populate the keys array with the keys
  25
+ * and return whatever has been matched.
  26
+ *
  27
+ * This method was taken from middleware-connect:
  28
+ * @link   https://github.com/senchalabs/connect/blob/master/lib/connect/middleware/router.js
  29
+ *
  30
+ * @param  {String} The path to normalise and retrieve the parameters from.
  31
+ * @param  {Array}  An array of keys retrieved from the routes.
  32
+ * @return {Object} A RegExp object ready to be "exec"ed 
  33
+*/
  34
+
  35
+Router.prototype.normalisePath = function (path, keys) {
  36
+    path = path.concat('/?').replace(/\/\(/g, '(?:/')
  37
+        .replace(/(\/)?(\.)?:(\w+)(\?)?/g, function(m, slash, format, key, optional) {
  38
+            keys.push(key);
  39
+            return ''
  40
+                + (optional ? '' : slash || '') + '(?:'
  41
+                + (format || '') + '([^/.]+))';
  42
+        })
  43
+        .replace(/([\/.])/g, '\\$1')
  44
+        .replace(/\*/g, '(.+)');
  45
+    return new RegExp('^' + path + '$', 'i');
  46
+}
  47
+
  48
+/**
  49
+ * This method matches the urls.
  50
+ *
  51
+ * This method superceeds the previous "match" methdo that was matchin
  52
+ * only the static routes. 
  53
+ *
  54
+ * With this method, we are able to identify URIs as such as /name/:key and
  55
+ * return the {'key': 'value'}.
  56
+ *
  57
+ * In the event where nothing has been identified, we verify if the two urls
  58
+ * are the same and if they are, we return true. If the return value is an empty
  59
+ * object '{}' we return false.
  60
+ *
  61
+ * @param  {String} The active route to match.
  62
+ * @param  {String} The expected route that should look like the activeroute
  63
+ *                  or at least match once normalised.
  64
+ *
  65
+ * @return {Mixed}  Either a boolean true if the url is the exact same one (static),
  66
+ *                  either a false if nothing has been matched, or an object of key-value
  67
+ *                  of dynamic parameters identified by the Router.
  68
+ */
  69
+Router.prototype.matchDynamic = function (activeRoute, expectedRoute) {
  70
+    var keys = [];
  71
+    var path = this.normalisePath(activeRoute, keys);
  72
+    
  73
+    var retValue = {};
  74
+    
  75
+    if (matched = path.exec(expectedRoute)) {
  76
+        for (var i = 1; i < matched.length; i++) {
  77
+            if (typeof matched[i] === 'string') {
  78
+                retValue[keys[i-1]] = matched[i];
  79
+            }
  80
+        }
  81
+    } else {
  82
+        if (activeRoute == expectedRoute) {
  83
+            return true;
  84
+        }
20 85
     }
21 86
     
22  
-    return false;
  87
+    return JSON.stringify(retValue) == '{}' ? false : retValue;
23 88
 };
24 89
 
25 90
 /**
26 91
  * This is where the content negotiation and what kind of 
27  
- * response is returned to the users
  92
+ * response is returned to the users.
  93
+ *
28 94
  * @param {Object} An object of the HTTP Request from require('http') containing
29 95
  *                 the request information.
30 96
  *
@@ -151,8 +217,11 @@ Restlike.prototype.match = function(route, callback) {
151 217
     var response = {};
152 218
     var httpMethod = this.request.method.toLowerCase();
153 219
 
154  
-    if (router.match(route, this.request.url)) {
155  
-        var caller = eval('callback.'+httpMethod);
  220
+    if (matchedRoute = router.matchDynamic(route, this.request.url)) {
  221
+        var caller = function() { 
  222
+            return callback[httpMethod](matchedRoute); 
  223
+        };
  224
+
156 225
         response = content.negotiate(caller(url.parse(this.request.url, true).query));
157 226
         if (response.headers) {
158 227
             this.response.writeHead(response.statusCode, response.headers);
@@ -164,4 +233,4 @@ Restlike.prototype.match = function(route, callback) {
164 233
 };
165 234
 
166 235
 // The node.js exports
167  
-exports.Restlike = Restlike;
  236
+exports.Restlike = Restlike;
6  server.js
@@ -4,9 +4,9 @@ var restlike = require('./lib/restlike');
4 4
 
5 5
 http.createServer(function (request, response) {
6 6
     var rest = new restlike.Restlike(request, response);
7  
-    rest.match('/time/to/go', {
8  
-        get: function() {
9  
-            return [1,2,3];
  7
+    rest.match('/who/:are/you/:really', {
  8
+        get: function(data) {
  9
+            return data;
10 10
         }
11 11
     });
12 12
 

0 notes on commit 7064129

Please sign in to comment.
Something went wrong with that request. Please try again.