Koa-Router

  • Express 式路由使用app.get, app.put, app.post
  • Named URL parameters and regexp captures
  • String or regular expression route matching
  • Named Routes with URL generation
  • Responds to OPTIONS request with allowed methods
  • Support for 405 Method Not Allowed and 501 Not Implemented
  • Multiple route middleware
  • Multiple routers

安装

npm install koa-router
`</pre>

### 使用

<pre>`var koa = require("koa"),
    router = require("koa-router"),
    app = koa();

app.use(router(app))
`</pre>

After the router has been initialized you can register routes:

<pre>`app.get("/users/:id", function*(next){
  var user = yield User.findOne(this.params.id);
  this.body = user;
});
`</pre>

### 多路由

You can use multiple routers and sets of routes by omitting the `app` argument. For example, separate routes for two versions of an API:

<pre>`var koa = require("koa"),
    mount = require("mount"),
    Router = require("koa-router");

var app = koa();

var APIv1 = new Router();
var APIv2 = new Router();

APIv1.get("/sign-in", function*(){
  // ...
})
APIv2.get("/sign-in", function*(){
  // ...
})

app.use(mount("/v1", APIv1.middleware())).use(mount("/v2", APIv2.middleware()));
`</pre>

### 链

The http methods(get, post, etc) return their `Router` instance, so routes can be chained as you're used to with express:

<pre>`var api = new Router();

api.get("/foo", showFoo).get("/bar", showBar).post("/foo", createFoo)

编写 Koa 中间件

Koa middlewares are simple function which return a GeneratorFunction, and accept another (middleware). When the middleware is run by an “upstream” middleware, it must manually yield to the “downstream” middleware.

For example if you wanted to track how long it takes for a request to propagate through Koa by adding an x-Response-Time header field the middleware would look like the following:

function *responseTime(next){
  var start = new Date;
  yield next;
  var ms = new Date - start;
  this.set("X-Response-Time", ms+"ms");
}
app.use(responseTime);
`</pre>

Here is another way to write the same thing, inline:

<pre>`app.use(function *(next){
  var start = new Date;
  yield next;
  var ms = new Date - start;
  this.set("X-Response-Time", ms+"ms");
});
`</pre>

### 中间件最佳实践

Imcluding Middleware accepting options, named middleware for debugging, among others

#### 中间件选项

When creating public middleware it's useful to conform to the convention of wrapping the middleware in a function that accepts options, allowing users to extend functionality. Even if your middleware accepts no options, this is still a good idea to keep things uniform.

Here our contrived `logger` middleware accepts a `format` string for customization, and returns the middleware itself:

<pre>`function logger(format){
  format = format || ":method\":url\"";
  return function*(next){
    var str = format.replace(":method", this.method).replace(":url", this.url);
    console.log(str);
    yield next;
  }
}
`</pre>

app.use(logger());
app.use(logger(":method:url"))

<pre>`
### 命名中间件
Naming middlewares is optional, however it's useful for debugging purpose to assign a name
`</pre>

function logger(format){
  return function *logger(next){
    // ...
  }
}

<pre>`### 结合多个中间件
Sometimes you want to "compose" multiple middleware into a single middleware for easy re-use or exporting. To do so, you may chain them together with `.call(this, next)`, then return another function that yields the chain

function _random(next) {
if (‘/random’ == this.path) {
this.body = Math.floor(Math.random()_10);
} else {
yield next;
}
};

function *backwards(next) {
if (‘/backwards’ == this.path) {
this.body = ‘sdrawkcab’;
} else {
yield next;
}
}

function *pi(next) {
if (‘/pi’ == this.path) {
this.body = String(Math.PI);
} else {
yield next;
}
}

function *all(next) {
yield random.call(this, backwards.call(this, pi.call(this, next)));
}

app.use(all);
`

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×