Giter Club home page Giter Club logo

koa-router's Introduction

koa-router

NPM version NPM Downloads Node.js Version Build Status Gitter Chat

Router middleware for koa

  • Express-style routing using app.get, app.put, app.post, etc.
  • Named URL parameters.
  • Named routes with URL generation.
  • Responds to OPTIONS requests with allowed methods.
  • Support for 405 Method Not Allowed and 501 Not Implemented.
  • Multiple route middleware.
  • Multiple routers.
  • Nestable routers.
  • ES7 async/await support.

Migrating to 7 / Koa 2

  • The API has changed to match the new promise-based middleware signature of koa 2. See the koa 2.x readme for more information.
  • Middleware is now always run in the order declared by .use() (or .get(), etc.), which matches Express 4 API.

Installation

Install using npm:

npm install koa-router

API Reference

Router ⏏

Kind: Exported class

new Router([opts])

Create a new router.

Param Type Description
[opts] Object
[opts.prefix] String prefix router paths

Example
Basic usage:

var Koa = require('koa');
var Router = require('koa-router');

var app = new Koa();
var router = new Router();

router.get('/', (ctx, next) => {
  // ctx.router available
});

app
  .use(router.routes())
  .use(router.allowedMethods());

router.get|put|post|patch|delete|del ⇒ Router

Create router.verb() methods, where verb is one of the HTTP verbs such as router.get() or router.post().

Match URL patterns to callback functions or controller actions using router.verb(), where verb is one of the HTTP verbs such as router.get() or router.post().

Additionaly, router.all() can be used to match against all methods.

router
  .get('/', (ctx, next) => {
    ctx.body = 'Hello World!';
  })
  .post('/users', (ctx, next) => {
    // ...
  })
  .put('/users/:id', (ctx, next) => {
    // ...
  })
  .del('/users/:id', (ctx, next) => {
    // ...
  })
  .all('/users/:id', (ctx, next) => {
    // ...
  });

When a route is matched, its path is available at ctx._matchedRoute and if named, the name is available at ctx._matchedRouteName

Route paths will be translated to regular expressions using path-to-regexp.

Query strings will not be considered when matching requests.

Named routes

Routes can optionally have names. This allows generation of URLs and easy renaming of URLs during development.

router.get('user', '/users/:id', (ctx, next) => {
 // ...
});

router.url('user', 3);
// => "/users/3"

Multiple middleware

Multiple middleware may be given:

router.get(
  '/users/:id',
  (ctx, next) => {
    return User.findOne(ctx.params.id).then(function(user) {
      ctx.user = user;
      next();
    });
  },
  ctx => {
    console.log(ctx.user);
    // => { id: 17, name: "Alex" }
  }
);

Nested routers

Nesting routers is supported:

var forums = new Router();
var posts = new Router();

posts.get('/', (ctx, next) => {...});
posts.get('/:pid', (ctx, next) => {...});
forums.use('/forums/:fid/posts', posts.routes(), posts.allowedMethods());

// responds to "/forums/123/posts" and "/forums/123/posts/123"
app.use(forums.routes());

Router prefixes

Route paths can be prefixed at the router level:

var router = new Router({
  prefix: '/users'
});

router.get('/', ...); // responds to "/users"
router.get('/:id', ...); // responds to "/users/:id"

URL parameters

Named route parameters are captured and added to ctx.params.

router.get('/:category/:title', (ctx, next) => {
  console.log(ctx.params);
  // => { category: 'programming', title: 'how-to-node' }
});

The path-to-regexp module is used to convert paths to regular expressions.

Kind: instance property of Router

Param Type Description
path String
[middleware] function route middleware(s)
callback function route callback

router.routes ⇒ function

Returns router middleware which dispatches a route matching the request.

Kind: instance property of Router

router.use([path], middleware) ⇒ Router

Use given middleware.

Middleware run in the order they are defined by .use(). They are invoked sequentially, requests start at the first middleware and work their way "down" the middleware stack.

Kind: instance method of Router

Param Type
[path] String
middleware function
[...] function

Example

// session middleware will run before authorize
router
  .use(session())
  .use(authorize());

// use middleware only with given path
router.use('/users', userAuth());

// or with an array of paths
router.use(['/users', '/admin'], userAuth());

app.use(router.routes());

router.prefix(prefix) ⇒ Router

Set the path prefix for a Router instance that was already initialized.

Kind: instance method of Router

Param Type
prefix String

Example

router.prefix('/things/:thing_id')

router.allowedMethods([options]) ⇒ function

Returns separate middleware for responding to OPTIONS requests with an Allow header containing the allowed methods, as well as responding with 405 Method Not Allowed and 501 Not Implemented as appropriate.

Kind: instance method of Router

Param Type Description
[options] Object
[options.throw] Boolean throw error instead of setting status and header
[options.notImplemented] function throw the returned value in place of the default NotImplemented error
[options.methodNotAllowed] function throw the returned value in place of the default MethodNotAllowed error

Example

var Koa = require('koa');
var Router = require('koa-router');

var app = new Koa();
var router = new Router();

app.use(router.routes());
app.use(router.allowedMethods());

Example with Boom

var Koa = require('koa');
var Router = require('koa-router');
var Boom = require('boom');

var app = new Koa();
var router = new Router();

app.use(router.routes());
app.use(router.allowedMethods({
  throw: true,
  notImplemented: () => new Boom.notImplemented(),
  methodNotAllowed: () => new Boom.methodNotAllowed()
}));

router.redirect(source, destination, [code]) ⇒ Router

Redirect source to destination URL with optional 30x status code.

Both source and destination can be route names.

router.redirect('/login', 'sign-in');

This is equivalent to:

router.all('/login', ctx => {
  ctx.redirect('/sign-in');
  ctx.status = 301;
});

Kind: instance method of Router

Param Type Description
source String URL or route name.
destination String URL or route name.
[code] Number HTTP status code (default: 301).

router.route(name) ⇒ Layer | false

Lookup route with given name.

Kind: instance method of Router

Param Type
name String

router.url(name, params, [options]) ⇒ String | Error

Generate URL for route. Takes a route name and map of named params.

Kind: instance method of Router

Param Type Description
name String route name
params Object url parameters
[options] Object options parameter
[options.query] Object | String query options

Example

router.get('user', '/users/:id', (ctx, next) => {
  // ...
});

router.url('user', 3);
// => "/users/3"

router.url('user', { id: 3 });
// => "/users/3"

router.use((ctx, next) => {
  // redirect to named route
  ctx.redirect(ctx.router.url('sign-in'));
})

router.url('user', { id: 3 }, { query: { limit: 1 } });
// => "/users/3?limit=1"

router.url('user', { id: 3 }, { query: "limit=1" });
// => "/users/3?limit=1"

router.param(param, middleware) ⇒ Router

Run middleware for named route parameters. Useful for auto-loading or validation.

Kind: instance method of Router

Param Type
param String
middleware function

Example

router
  .param('user', (id, ctx, next) => {
    ctx.user = users[id];
    if (!ctx.user) return ctx.status = 404;
    return next();
  })
  .get('/users/:user', ctx => {
    ctx.body = ctx.user;
  })
  .get('/users/:user/friends', ctx => {
    return ctx.user.getFriends().then(function(friends) {
      ctx.body = friends;
    });
  })
  // /users/3 => {"id": 3, "name": "Alex"}
  // /users/3/friends => [{"id": 4, "name": "TJ"}]

Router.url(path, params [, options]) ⇒ String

Generate URL from url pattern and given params.

Kind: static method of Router

Param Type Description
path String url pattern
params Object url parameters
[options] Object options parameter
[options.query] Object | String query options

Example

var url = Router.url('/users/:id', {id: 1});
// => "/users/1"

const url = Router.url('/users/:id', {id: 1}, {query: { active: true }});
// => "/users/1?active=true"

Contributing

Please submit all issues and pull requests to the alexmingoia/koa-router repository!

Tests

Run tests using npm test.

Support

If you have any problem or suggestion please open an issue here.

koa-router's People

Contributors

aheckmann avatar alexmingoia avatar bguiz avatar bitinn avatar creativecactus avatar dizlexik avatar dominicbarnes avatar drgrove avatar fengmk2 avatar frederickfogerty avatar heavenduke avatar ifroz avatar iliakan avatar ilkkao avatar jbielick avatar jeffijoe avatar jergason avatar jeynish avatar joesonw avatar kilianc avatar mikefrey avatar richardprior avatar secretfader avatar t3chnoboy avatar tankenstein avatar tj avatar vikramdurai avatar vkhv avatar wachunei avatar yiminghe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

koa-router's Issues

Properly use Semantic Versioning

I may be wrong but I think npm assumes that modules author are following the Semantic Versioning spec. This means that when adding dependencies with --save it will automatically add an entry inside package.json like: "koa-router": "~2.3.1".

It implies that npm can safely install any versions >=2.3.1-0 <2.4.0-0 of that module because the author is not going to introduce any non backwards-compatible bug fixes.

Unfortunately, between versions 2.3.1 and 2.3.2 you allowed multiple routes to be matched changing the behaviour for apps relying on your module.

Would you mind applying the recommendation below "What do I do if I accidentally release a backwards incompatible change as a minor version?"?

Thanks 👍

wrong middleware behavior

Not matching methods always returns a 501, because a return statement is missing after this I think

      // matches path but not method, so return 405 Method Not Allowed
      // unless this is an OPTIONS request.
      this.status = (this.method === 'OPTIONS' ? 204 : 405);
      this.set('Allow', Object.keys(methodsAvailable).join(", "));

Also I have this configuration:

  public.get('/:role/:id/picture', require('./users/picture').getPicture)
  private.put('/:role/:id/picture', require('./users/picture').setPicture)

  var api = compose([
    public.middleware(),
    auth(), me(), acl(),
    private.middleware()
  ])

calling PUT /admins/5/picture will always respond with 405. Any advice on how to shape this?

Top level resource problem

node: v0.11.10
koa: 0.3.0
koa-router: 2.4.1

app.resource('name',{ index: function*(){ this.body = 'Ok' } }); works correctly. If i open http://127.0.0.1/name I get Ok.

If I omit the resource name, what I expect to happen is what you state in README.md:

Omit the resource name to specify a top-level resource:

So the following code

var app = require('koa')();
var kr = require('koa-router');
app.use(kr(app));

app.resource({ index: function *(){ this.body = 'Index';} });
app.listen(8080);

should give "Index" when I point the browser to http://127.0.0.1:8080 but all I get is "Not Found".

The debugger says:

Tue, 28 Jan 2014 11:54:39 GMT koa-router GET /

Am I doing something wrong?

path-to-regexp

Might want to use that for Express parity, otherwise good stuff :D

Multiple matching routes

Am I correct that this is not possible:

app.all(/^\/api/, function *(next) {
    if (this.cookies.get('secret' !== 'foo') this.throw('unauthorized');
    yield next;
});

app.post('/api/something', function *(next) {
    // API user is authenticated
});

Would it make any sense to support this kind of filters?

Add method functions also to router prototype

Can you also add the functions get,post,... to the router prototype?

I'd like to use the router as standalone middleware that does not modify the app object. Instead, I want to define the routes directly on the router.

For example:

var app = koa();
app.use(router()
    .get("/",indexPageMiddleware)
    .get("/sub/",subPageMiddleware)
);
app.listen(80)

also, I could imagine the need for nested routers, which is currently not possible. Adding the methods also to router instances would solve this problem, too.

What do you think?

allow params post-processing

Express had a way to post-process app.params.

For example, a param with name :id could be cast to ObjectId (and if fails, throw 404), or :userId becomes the autoloaded user.

In the particular case of using Mongo/Mongoose that was quite helpful, because if a param does not validate as ObjectId, then findById(id) and findOne(_id: id) methods throw CastError.

To handle the error, we need to either to validate it manually (in try..catch) in every route which uses user-provided id, or just rely on a global agreement (implemented by post-processing params) ":id or :...Id" are ObjectIds" could be helpful.

P.S. This functionality seems to exist for koa-route: https://github.com/segmentio/koa-params
Why not to implement it here, it fits nicely.

Doc could be clearer

Under the multiple routers example we have a function mount in scope but it doesn't show where this comes from.

As somebody trying koa out for the first time, I don't know what I need to require to bring this function in.

call next from resource controller?

When using app.resource('users', require('./user')) How can I call next on my user controller to continue with the following middleware or bubble up if it's the last one?

Can't figure out... sorry if it's a dumb question

Multiple middleware doesn't work

app.get(
  '/test/:id',
  function *(next) {
    this.user =  { id: 17, name: "Alex" };
    yield next;
  },
  function *(next) {
    this.body = this.user;
  }
);

results in

Error: yield a function, promise, generator, array, or object
    at next (/Users/Malte/Projects/PhotoApp/node_modules/koa/node_modules/co/index.js:108:12)
    at Object.<anonymous> (/Users/Malte/Projects/PhotoApp/node_modules/koa/node_modules/co/index.js:56:5)
    at next (/Users/Malte/Projects/PhotoApp/node_modules/koa/node_modules/co/index.js:92:21)
    at Object.<anonymous> (/Users/Malte/Projects/PhotoApp/node_modules/koa/node_modules/co/index.js:56:5)
    at next (/Users/Malte/Projects/PhotoApp/node_modules/koa/node_modules/co/index.js:92:21)
    at Object.<anonymous> (/Users/Malte/Projects/PhotoApp/node_modules/koa/node_modules/co/index.js:56:5)
    at next (/Users/Malte/Projects/PhotoApp/node_modules/koa/node_modules/co/index.js:92:21)
    at Object.<anonymous> (/Users/Malte/Projects/PhotoApp/node_modules/koa/node_modules/co/index.js:56:5)
    at next (/Users/Malte/Projects/PhotoApp/node_modules/koa/node_modules/co/index.js:92:21)
    at Object.<anonymous> (/Users/Malte/Projects/PhotoApp/node_modules/koa/node_modules/co/index.js:56:5)

koa-router and introspection / documentation

I would like to create a koa-router plugin that opens an api on koa-router's internal structures :

  • list all defined routes
  • dry-run matching
  • simulation of route matching
  • documentation of a route
  • create a new route

have you given a thought already about such a thing ? I don't know for example if koa-router should be extended with an object allowing for more meta fields on each routes (created_dt, registered_dt, documentation, ...) or if the 'name' of the route should be used as a sort of primary key in the plugin to allow for configuration of routes kept in the external plugin. Since name is optional that could be a problem.

thanks for your feedback

respond_to format

It would be awesome to have a respondTo(format) method or similar plumbing in this.

E.g.

app.resource('users', {
  // GET /users (default format: html)
  // GET /users.json
  // GET /users.xml
  // GET /users.csv
  index: function *(next) {
    // this.format in ['html', 'json', 'xml', 'csv']
  }
});

genericity of path matching rules

Hello,

currently koa-router uses path-to-regexp for the pattern matching. It would interesting to be able to define more complex routing schemes while keeping the named aspect of things.

for example in hapi https://github.com/spumko/hapi/blob/master/docs/Reference.md#path-processing they have

/a/{name}/b
/a{name}/b/{var*2}

the fact the you have a start delimiter + and end delimiter allows to have more complex patterns.

/{name}ly/b versus
/:namely/b

This is just one example there are probably yet other ways of defining programmer-friendly routes. Maybe even the pattern matcher should be pluggable.

Getting params when doing a post

Hello all!
When trying to post

{"title":"test"}

to this

app.post('/users/:id', function *(next) {
  console.log(this.params.title)
  console.log(this.params.id)
});

it outputs that title is undefined, but ID is not.

Is there something I'm missing?

Reversed named route

Is there a way to get the name of the named route once koa is running?

Thanks

validation rules

It could be a cool addition to koa router to integrate a rule-matcher in its API :

step1: match the path with a regexp (using :notation of {notation})
step2: validate the rules according to a definition (path rules, query rules, post rules)

It should not be coded inside koa-router since koa-router could leverage on existing rule matchers such as https://github.com/spumko/joi. There are probably other out there and the best would be to have a consolidatefor rule matchers if it does not already exist.

Named regex routes broken in 3.2.2

Routes of this type broke in v3.2.2 (worked fine in v3.2.1):

app.get('my_route', /^\/my\/route$/, function* myRoute(next) {
    // ...
});

This is the error being thrown:

Error: get `my_route`: `middleware` must be a function, not `object`

Named routes

Is it possible to generate url for specific route not to hardcode them in templates?

Support for named middleware stacks

Ideally, you should be able to define stacks of middleware like so:

router.define('parse', [
cookieParser,
bodyParser
]);

router.get('/', 'parse', handler);

Request going to wrong route

I have an application like this:

app.get("/time", function * (next) {
})
.get("/scroll", function * (next) {
})
.get("/track",function * (next) {
});

Now the client is sending requests via a web bug like:

(new Image()).src = APP + '/track?' + data;

And I'm getting puzzled because requests that should go to the track route are also going to the scroll route and throwing errors, what could I be doing wrong?

ability to short circuit a chain of callbacks

currently, the router looks to be just iterating through the callbacks, yielding each one, then building an arg list.

   for (var len = route.callbacks.length, i=0; i<len; i++) {
     ...

It would be really nice if a callback could trigger a short circuit and finish. a common use case would be to validate in the first callback, then either return a validation error or continue on.

I can think of a few workarounds that would work currently, like bypassing the multiple callback paradigm and just passing the router 1 generated function that wraps everything up. I'm sure there are other ways.

A change like this may break any current router implementations though....

Support early 404 status

It would be great to have the ability to know if the path + http method is going to be resolved to an endpoint or 404.

The classical example is an auth middleware right before the router middleware.

If the route is 404 I want to save the query to check the auth token and all the business logic.

module.exports = function () {
  return function *auth(next) {
    if (this.pathIsResoved()) {
      this.auth = yield authorize.call(this, this.get('x-auth-token'))
    }
    yield next
  }
}

pathIsResoved sucks as name, but you get the idea :)

2.4.2 to npm

npm seems to be still @ 2.3.3, looking forward the RegExp params =)))

~/workspace/az/routific-landing/api $ npm i
npm WARN package.json [email protected] No repository field.
npm http GET https://registry.npmjs.org/koa-router/2.4.2
npm http 404 https://registry.npmjs.org/koa-router/2.4.2
npm ERR! Error: version not found: 2.4.2 : koa-router/2.4.2

Question: how should one implement prepended urls?

What would the correct way to handle static file requests through sitename.com/ and api requests through api.sitename.com/ with koa-router. Maybe a bit of a general question, but I was hoping you could point me in the right direction.

Add an option to `resource.add` to keep resource original routes

var candidates = router.resource('candidates', require('./candidates'))
var jobs = router.resource('jobs', require('./jobs'))

// replaces "/candidates" with "/jobs/:id/candidates"
jobs.add(candidates) 

API proposal

var candidates = router.resource('candidates', require('./candidates'))
var jobs = router.resource('jobs', require('./jobs'))

// keeps both "/candidates" and "/jobs/:id/candidates"
jobs.add(candidates, copy=true) 

or

var candidates = router.resource('candidates', require('./candidates'))
var jobs = router.resource('jobs', require('./jobs'))

router.root.add(candidates)
jobs.add(candidates) 

temp workaround

var candidates = router.resource('candidates', require('./candidates'))
var jobs = router.resource('jobs', require('./jobs'))

// replaces "/candidates" with "/jobs/:id/candidates"
jobs.add(candidates) 

// readds "/candidates"
router.resource('candidates', require('./candidates'))

Can't use with koa-render?

app.get("/", function *(){
    this.body = yield this.render("index");
});

then throw
TypeError: Object # has no method 'render'

Make regexp capture groups available in this.params

Might it be useful to make capture groups available in this.params somehow, when using a regexp to match the path? Something like this (in route.match) when using a regexp like /_\/([^\/]+)\/([^\/]+)/ to match a path like /_/foo/bar?

for (var len = this.paramsArray.length, i=0; i<len; i++) {
  if (this.isRegexp) { // or something similar
    this.params['m' + i] = this.paramsArray[i];
  } else {
    if (this.paramNames[i]) {
      this.params[this.paramNames[i].name] = this.paramsArray[i];
    }
  }
}

resulting in this.params containing:

{ m0: 'foo', m1: 'bar' }

This was useful to me, but that could be because I’m thinking about it wrongly.

Broken nested routing

Since 2.3.0 nested resources routing doesn't work right. Here is simple example:

var app = require('koa')()
    , router = require('koa-router')(app)

app.use(router);

var forums = app.resource('forums', {
  // GET /forums
  index: function *(next) {
    this.body = { route: 'forums/' }
    console.log(this.params)
  },
  // GET /forums/new
  new: function *(next) {},
  // POST /forums
  create: function *(next) {},
  // GET /forums/:id
  show: function *(next) {
    this.body = 'Response from forums'
    // console.log(this.params)
  },
  // GET /forums/:id/edit
  edit: function *(next) {},
  // PUT /forums/:id
  update: function *(next) {},
  // DELETE /forums/:id
  destroy: function *(next) {}
});

var threads = app.resource('threads', {
  // GET /threads
  index: function *(next) {
    this.body = { route: 'threads/' }
    console.log(this.params)
  },
  // GET /threads/new
  new: function *(next) {},
  // POST /threads
  create: function *(next) {},
  // GET /threads/:id
  show: function *(next) {
    this.body = { route: '/forums/:forum/threads/:thread', 
    'forum':this.params['forum'],
    'thread':this.params['thread']
    }
    console.log(this.params)
  },
  // GET /threads/:id/edit
  edit: function *(next) {},
  // PUT /threads/:id
  update: function *(next) {},
  // DELETE /threads/:id
  destroy: function *(next) {}
});

// nested resources routing
forums.add(threads);

// response
app.use(function *(){
  this.body = 'Try GET /forums/54/threads/12';
});

app.listen(3000);

When you will try to GET /forums/54/threads/12 then this.params will contain this:

[ thread: '54' ]

Parametr forum is missing and parametr thread contains wrong value 54 instead of 12.

Express-like parameter preprocessing

/Opening a new issue, apart from basics in #74/

Express had a great, polished up parameter preprocessing.

How about to implement it in koa-router?

Citing http://expressjs.com/api#app.param:

This example is a bit more advanced. It is checking if the second argument is a regular expression, returning the callback, which acts much like the "user" param example.

app.param(function(name, fn){
  if (fn instanceof RegExp) {
    return function(req, res, next, val){
      var captures;
      if (captures = fn.exec(String(val))) {
        req.params[name] = captures;
        next();
      } else {
        next('route');
      }
    }
  }
});

The method could now be used to effectively validate parameters (and optionally parse them to provide capture groups):

app.param('id', /^\d+$/);

app.get('/user/:id', function(req, res){
  res.send('user ' + req.params.id);
});

app.param('range', /^(\w+)\.\.(\w+)?$/);

app.get('/range/:range', function(req, res){
  var range = req.params.range;
  res.send('from ' + range[1] + ' to ' + range[2]);
});

Express implementation covers both regexp matching (I can convert /^.*?Id$/ to ids) and validation which is kind-a cool. A passthrough function instead of == param.name comparison is flexible and neat.

hello, I have some trouble with koa-router

I use koa-router just like connect, but I found it din't work, here is my code in connect:

  • connect.
    When I visit 'xxx.com/test', it'll through m1, then to m2.
app.use( '/', m1 );
app.use( '/test', m2 );
  • koa-router.
    When I visit 'xxx.com/test', it just came to m2.
r1 = new KoaRouter();
r2 = new KoaRouter();
r1.get( '/', m1 );
r2.get( '/test', m2 );
app.use( r1.middleware() );
app.use( r2.middleware() );

or like this way.

app.use( KoaRouter( app ) );
app.get( '/', m1 );
app.get( '/test', m2 );

Is there some problem in my code? I want to log some access information.
Thank you every much.

koa.session and koa-router problem

Please have a look at this issue as it might be of you interest.

I've runned the same Makefile with DEBUG=koa-router and the output is

koa-router defined route GET /test/print +0ms
koa-router defined route POST /test/:v +8ms
koa-router POST /test/42 +1s
  koa-router test "/test/print" /^\/test\/print\/?$/i +1ms
  koa-router test "/test/:v" /^\/test\/(?:([^\/]+?))\/?$/i +0ms
  koa-router match "/test/:v" /^\/test\/(?:([^\/]+?))\/?$/i +1ms
  koa-router dispatch "/test/:v" /^\/test\/(?:([^\/]+?))\/?$/i +0ms
TypeError: Cannot set property 'value' of undefined
koa-router GET /test/print +2s
  koa-router test "/test/print" /^\/test\/print\/?$/i +0ms
  koa-router match "/test/print" /^\/test\/print\/?$/i +0ms
  koa-router test "/test/:v" /^\/test\/(?:([^\/]+?))\/?$/i +0ms
  koa-router match "/test/:v" /^\/test\/(?:([^\/]+?))\/?$/i +0ms
  koa-router dispatch "/test/print" /^\/test\/print\/?$/i +1ms
TypeError: Cannot read property 'value' of undefined

add some debug()s

to get a better idea of what's being defined internally when debugging an app, specifically for the resources/routes defined and then match attempts so you can see if a regexp was failing etc

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.