JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 11
  • Score
    100M100P100Q67686F

A trie router for toa.

Package Exports

  • toa-router

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (toa-router) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

toa-router

A trie router for toa.

NPM version Build Status Downloads

Toa

Features

  • OPTIONS support
  • 405 Method Not Allowed support
  • 501 Not Implemented support
  • multi router support with different url prefix

Demo

'use strict'
// **Github:** https://github.com/toajs/toa
//
// **License:** MIT
var Toa = require('toa')
var Router = require('toa-router')

var router = new Router()

router
  .get('', function () {
    // sync handle
    this.body = this.method + ' ' + this.path
  })
  .get('/promise', function () {
    // promise handle
    var ctx = this
    return Promise.resolve().then(function () {
      ctx.body = ctx.method + ' ' + ctx.path
    })
  })
  .get('/thunk', function () {
    // thunk handle
    return function (done) {
      this.body = this.method + ' ' + this.path
      done()
    }
  })
  .get('/generator', function *() {
    // generator handle
    this.body = this.method + ' ' + this.path
  })

var app = Toa(function *() {
  yield router
})

app.listen(3000, function () {
  console.log('Listened 3000')
})

Installation

npm install toa-router

API

var Router = require('toa-router')

Five usage in Toa:

There five usages for toa-router, but only One think: thunk

Usage 1:

var app = Toa(function () {
  return router.route(this)
})

Usage 2:

var app = Toa(function () {
  return router
})

Usage 3:

var app = Toa(function *() {
  yield router.route(this)
})

Usage 4:

var app = Toa(function *() {
  yield router
})

Usage 5:

var app = Toa()
app.use(router.toThunk())

new Router([root])

  • root Option, String, define the router's scope。
var router = new Router()
var APIRouter = new Router('/api')

Router.prototype.route(context)

Run the router with context.

Toa(function () {
  return router.route(this)
}).listen(3000)

Router.prototype.define(pattern)

Define a route with the url pattern.

var route = router.define('/:type/:id')

route.get(function () {})
  .put(function () {})
  .post(function () {})
  .del(function () {})
// support all `http.METHODS`: 'get', 'post', 'put', 'head', 'delete', 'options', 'trace', 'copy', 'lock'...

Router.prototype.get(pattern, handler)

Router.prototype.put(pattern, handler)

Router.prototype.post(pattern, handler)

Router.prototype.del(pattern, handler)

And more http.METHODS ('head', 'delete', 'options', 'trace', 'copy', 'lock'...)

Support generator handler:

router
  .get('/:type/:id', function *() {
    // ...
  })
  .put('/:type/:id', function *() {
    // ...
  })

Router.prototype.otherwise(handler)

Set default route definition that will be used when no other route definition is matched.

Pattern Definitions

For pattern definitions, see route-trie.

Each fragment of the pattern, delimited by a /, can have the following signature:

  • string - simple string.

    Define /post will matched:

    '/post'
  • string|string - | separated strings.

    Define /post|task will matched:

    '/post'
    '/task'
  • :name - Wildcard route matched to a name.

    Define /:type will matched:

    '/post', with params `{type: 'post'}`
    '/task', with params `{type: 'task'}`
  • prefix:name - Wildcard route matched to a name.

    Define /api:type will matched:

    '/apipost', with params `{type: 'post'}`
    '/apitask', with params `{type: 'task'}`
  • (regex) - A regular expression match without saving the parameter (not recommended).

    Define /(post|task) will matched:

    '/post'
    '/task'

    Define /([a-z0-9]{6}) will matched:

    '/abcdef'
    '/123456'
  • :name(regex)- Named regular expression match.

    Define /:type/:id([a-z0-9]{6}) will matched:

    '/post/abcdef', with params `{type: 'post', id: 'abcdef'}`
    '/task/123456', with params `{type: 'task', id: '123456'}`
  • prefix:name(regex)- Named regular expression match.

    Define /api:type/id:id([a-z0-9]{6}) will matched:

    '/apipost/idabcdef', with params `{type: 'post', id: 'abcdef'}`
    '/apitask/id123456', with params `{type: 'task', id: '123456'}`
  • (*) - Match remaining path without saving the parameter (not recommended).

    Define /(*) will match all path.

  • :name(*)- Named regular expression match, match remaining path.

    Define /:type/:other(*) will matched:

    '/post/abcdef', with params `{type: 'post', other: 'abcdef'}`
    '/post/abcdef/ghi', with params `{type: 'post', other: 'abcdef/ghi'}`
    '/a/b/c/d/e', with params `{type: 'a', other: 'b/c/d/e'}`

Notice from route-trie for regex pattern:

var trie = new Trie()
var node = trie.define('/abc/([0-9]{2})')
assert(trie.match('/abc/47').node === node)

var trie = new Trie()
var node = trie.define('/abc/(\d{2})')
trie.match('/abc/47')  // null
assert(trie.match('/abc/dd').node === node)

var trie = new Trie();
var node = trie.define('/abc/([a-z]{2})')
assert(trie.match('/abc/ab').node === node)

var trie = new Trie();
var node = trie.define('/abc/(\w{2})')
trie.match('/abc/ab')  // null
assert(trie.match('/abc/ww').node === node)

var trie = new Trie();
var node = trie.define('/abc/(\\w{2})')
assert(trie.match('/abc/ab').node === node)

Due to JS String Escape Notation: '\d' === 'd', trie.define('/abc/(\d{2})') === trie.define('/abc/(d{2})'). trie.define accept a string literal, not a regex literal, the \ maybe be escaped!

Router.prototype.toThunk()

Return a thunk function that wrap the router.

var app = Toa()
app.use(router.toThunk())

this.params, this.request.params

this.params will be defined with any matched parameters.

router
  .define('/:type(posts|tasks)')
  .get(function () {
    var data = null
    switch (this.params.type) {
      case 'posts':
        data = mockPosts
        break
      case 'tasks':
        data = mockTasks
        break
    }
    if (data) this.body = resJSON(data)
    else this.throw(404, this.path + ' is not found!')
  })

this.routedPath, this.request.routedPath

this.routedPath will be defined with routed path.

License

The MIT License (MIT)