Skip to content

Commit

Permalink
expose router engine for other implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeembrey committed May 4, 2015
1 parent 99893af commit 208e623
Show file tree
Hide file tree
Showing 8 changed files with 1,093 additions and 763 deletions.
73 changes: 73 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,79 @@ curl http://127.0.0.1:8080/such_path
> such_path
```

## Implementing Your Own Router

Implementing a custom path matching library on top of this module is as easy as using `Router.Engine`. For example, to implement an "exact" path matching module, we can do this:

```js
var Engine = require('router').Engine
var slice = Array.prototype.slice

/**
* Accepts the path and some options we defined in our engine.
*/
function toFunction (route, options) {
if (!options.end) {
return function (path) {
var matches = path.substr(0, route.length) === route

return matches ? { path: path } : false
}
}

return function (path) {
return path === route ? { path: path } : false
}
}

/**
* The constructor must return the engine instance.
*/
function ExactRouter (options) {
return Engine.call(this, options)
}

/**
* Inherits from the engine prototype.
*/
ExactRouter.prototype = Object.create(Engine.prototype)

/**
* Set up `Router#use` with our custom path matching implementation.
*/
ExactRouter.prototype.use = function () {
// Use a simple utility for supporting a single path argument like `router`.
var opts = Router.Engine.sanitizeArgs.apply(null, arguments)
var match = toFunction(opts.path, { end: false })

return Engine.prototype.use.call(this, opts.path, match, opts.callbacks)
}

/**
* Set up `Router#route` with our custom path patching implementation.
*/
ExactRouter.prototype.route = function (path) {
var match = toFunction(path, { end: true })

return Engine.prototype.route.call(this, path, match)
}

/**
* Set up all the router method shorthands.
*/
Engine.methods.forEach(function (method) {
ExactRouter.prototype[method] = function (path) {
var route = this.route(path)
route[method].apply(route, slice.call(arguments, 1))
return this
}
})
```

Both the path matching function and the path itself must be passed into the `route` and `use` engine methods. This is for debugging, so `path` should be a human-readable path name. `Engine#use` also accepts an array of handlers to immediately include. The match function must return an object of `{ path: string, params: object }` or `false` if it didn't match.

Note: The path matching utility should not throw errors. Decoding of parameters is handled by the engine.

## License

[MIT](LICENSE)
Expand Down
Loading

0 comments on commit 208e623

Please sign in to comment.