find-my-way
Advanced tools
Comparing version 1.5.0 to 1.6.0
14
bench.js
@@ -11,2 +11,4 @@ 'use strict' | ||
findMyWay.on('GET', '/user/:id', () => true) | ||
findMyWay.on('GET', '/customer/:name-:surname', () => true) | ||
findMyWay.on('GET', '/at/:hour(^\\d+)h:minute(^\\d+)m', () => true) | ||
findMyWay.on('GET', '/abc/def/ghi/lmn/opq/rst/uvz', () => true) | ||
@@ -21,2 +23,8 @@ | ||
}) | ||
.add('lookup dynamic multi-parametric route', function () { | ||
findMyWay.lookup({ method: 'GET', url: '/customer/john-doe' }, null) | ||
}) | ||
.add('lookup dynamic multi-parametric route with regex', function () { | ||
findMyWay.lookup({ method: 'GET', url: '/at/12h00m' }, null) | ||
}) | ||
.add('lookup long static route', function () { | ||
@@ -31,2 +39,8 @@ findMyWay.lookup({ method: 'GET', url: '/abc/def/ghi/lmn/opq/rst/uvz' }, null) | ||
}) | ||
.add('find dynamic multi-parametric route', function () { | ||
findMyWay.find('GET', '/customer/john-doe') | ||
}) | ||
.add('find dynamic multi-parametric route with regex', function () { | ||
findMyWay.find('GET', '/at/12h00m') | ||
}) | ||
.add('find long static route', function () { | ||
@@ -33,0 +47,0 @@ findMyWay.find('GET', '/abc/def/ghi/lmn/opq/rst/uvz') |
55
index.js
@@ -9,9 +9,13 @@ 'use strict' | ||
regex: 3 | ||
multi-param: 4 | ||
It's used for a parameter, that is followed by another parameter in the same part | ||
Char codes: | ||
'#': 35 | ||
'*': 42 | ||
'-': 45 | ||
'/': 47 | ||
':': 58 | ||
'*': 42 | ||
'?': 63 | ||
'#': 35 | ||
*/ | ||
@@ -58,2 +62,3 @@ | ||
if (path.charCodeAt(i) === 58) { | ||
var nodeType = 1 | ||
j = i + 1 | ||
@@ -63,5 +68,22 @@ this._insert(method, path.slice(0, i), 0, null, null, null) | ||
// isolate the parameter name | ||
while (i < len && path.charCodeAt(i) !== 47) i++ | ||
var isRegex = false | ||
while (i < len && path.charCodeAt(i) !== 47) { | ||
isRegex = isRegex || path[i] === '(' | ||
if (isRegex) { | ||
i = path.indexOf(')', i) + 1 | ||
break | ||
} else if (path.charCodeAt(i) !== 45) { | ||
i++ | ||
} else { | ||
break | ||
} | ||
} | ||
if (isRegex && (i === len || path.charCodeAt(i) === 47)) { | ||
nodeType = 3 | ||
} else if (i < len) { | ||
nodeType = 4 | ||
} | ||
var parameter = path.slice(j, i) | ||
var isRegex = parameter.indexOf('(') > -1 | ||
var regex = isRegex ? parameter.slice(parameter.indexOf('('), i) : null | ||
@@ -77,6 +99,7 @@ if (isRegex) regex = new RegExp(regex) | ||
if (i === len) { | ||
return this._insert(method, path.slice(0, i), regex ? 3 : 1, params, handler, store, regex) | ||
return this._insert(method, path.slice(0, i), nodeType, params, handler, store, regex) | ||
} | ||
this._insert(method, path.slice(0, i), regex ? 3 : 1, params, null, null, regex) | ||
this._insert(method, path.slice(0, i), nodeType, params, null, null, regex) | ||
i-- | ||
// wildcard route | ||
@@ -265,2 +288,22 @@ } else if (path.charCodeAt(i) === 42) { | ||
// multiparametric route | ||
if (kind === 4) { | ||
currentNode = node | ||
i = 0 | ||
if (node.regex) { | ||
var matchedParameter = path.match(node.regex) | ||
if (!matchedParameter) return | ||
i = matchedParameter[1].length | ||
} else { | ||
while (i < pathLen && path.charCodeAt(i) !== 47 && path.charCodeAt(i) !== 45) i++ | ||
} | ||
decoded = fastDecode(path.slice(0, i)) | ||
if (errored) { | ||
return null | ||
} | ||
params[pindex++] = decoded | ||
path = path.slice(i) | ||
continue | ||
} | ||
// route not found | ||
@@ -267,0 +310,0 @@ if (len !== prefixLen) return null |
{ | ||
"name": "find-my-way", | ||
"version": "1.5.0", | ||
"version": "1.6.0", | ||
"description": "Crazy fast http radix based router", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -23,3 +23,3 @@ # find-my-way | ||
router.on('GET', '/', (req, res, params) => { | ||
res.end('{"hello":"world"}') | ||
res.end('{"message":"hello world"}') | ||
}) | ||
@@ -54,36 +54,58 @@ | ||
#### on(method, path, handler, [store]) | ||
Register a new route, `store` is an object that you can access later inside the handler function. | ||
Register a new route. | ||
```js | ||
router.on('GET', '/', (req, res, params) => { | ||
router.on('GET', '/example', (req, res, params) => { | ||
// your code | ||
}) | ||
``` | ||
Last argument, `store` is used to pass an object that you can access later inside the handler function. If needed, `store` can be updated. | ||
```js | ||
router.on('GET', '/example', (req, res, params, store) => { | ||
assert.equal(store, { message: 'hello world' }) | ||
}, { message: 'hello world' }) | ||
``` | ||
// with store | ||
router.on('GET', '/store', (req, res, params, store) => { | ||
// the store can be updated | ||
assert.equal(store, { hello: 'world' }) | ||
}, { hello: 'world' }) | ||
##### on(methods[], path, handler, [store]) | ||
Register a new route for each method specified in the `methods` array. | ||
It comes handy when you need to declare multiple routes with the same handler but different methods. | ||
```js | ||
router.on(['GET', 'POST'], '/example', (req, res, params) => { | ||
// your code | ||
}) | ||
``` | ||
If you want to register a **parametric** path, just use the *colon* before the parameter name, if you need a **wildcard** use the *star*. | ||
<a name="supported-path-formats"></a> | ||
##### Supported path formats | ||
To register a **parametric** path, use the *colon* before the parameter name. For **wildcard** use the *star*. | ||
*Remember that static routes are always inserted before parametric and wildcard.* | ||
```js | ||
// parametric | ||
router.on('GET', '/example/:name', () => {})) | ||
router.on('GET', '/example/:userId', (req, res, params) => {})) | ||
router.on('GET', '/example/:userId/:secretToken', (req, res, params) => {})) | ||
// wildcard | ||
router.on('GET', '/other-example/*', () => {})) | ||
router.on('GET', '/example/*', (req, res, params) => {})) | ||
``` | ||
Regex routes are supported as well, but pay attention, regex are very expensive! | ||
Regular expression routes are supported as well, but pay attention, RegExp are very expensive in term of performance! | ||
```js | ||
// parametric with regex | ||
router.on('GET', '/test/:file(^\\d+).png', () => {})) | ||
// parametric with regexp | ||
router.on('GET', '/example/:file(^\\d+).png', () => {})) | ||
``` | ||
You can also pass an array of methods if you need to declare multiple routes with the same handler but different method. | ||
It's possible to define more than one parameter within the same couple of slash ("/"). Such as: | ||
```js | ||
router.on(['GET', 'POST'], '/', (req, res, params) => { | ||
// your code | ||
}) | ||
router.on('GET', '/example/near/:lat-:lng/radius/:r', (req, res, params) => {})) | ||
``` | ||
*Remember in this case to use the dash ("-") as parameters separator.* | ||
Finally it's possible to have multiple parameters with RegExp. | ||
```js | ||
router.on('GET', '/example/at/:hour(^\\d{2})h:minute(^\\d{2})m', (req, res, params) => {})) | ||
``` | ||
In this case as parameter separator it's possible to use whatever character is not matched by the regular expression. | ||
Having a route with multiple parameters may affect negatively the performance, so prefer single parameter approach whenever possible, especially on routes which are on the hot path of your application. | ||
<a name="shorthand-methods"></a> | ||
@@ -90,0 +112,0 @@ ##### Shorthand methods |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
55850
19
1586
175