Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose router engine for other implementations #29

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 82 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ $ npm install router

```js
var finalhandler = require('finalhandler')
var http = require('http')
var Router = require('router')
var http = require('http')
var Router = require('router')

var router = Router()

router.get('/', function (req, res) {
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
res.end('Hello World!')
Expand Down Expand Up @@ -179,11 +180,11 @@ router.route('/')

```js
// import our modules
var http = require('http')
var Router = require('router')
var http = require('http')
var Router = require('router')
var finalhandler = require('finalhandler')
var compression = require('compression')
var bodyParser = require('body-parser')
var compression = require('compression')
var bodyParser = require('body-parser')

// store our message to display
var message = "Hello World!"
Expand Down Expand Up @@ -244,8 +245,8 @@ curl http://127.0.0.1:8080/api/set-message -X PATCH -H "Content-Type: applicatio
### Example using mergeParams

```js
var http = require('http')
var Router = require('router')
var http = require('http')
var Router = require('router')
var finalhandler = require('finalhandler')

// this example is about the mergeParams option
Expand Down Expand Up @@ -295,6 +296,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 = Engine.sanitizeUse.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