Git Product home page Git Product logo

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

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?

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

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?

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']
  }
});

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 :)

Can't use with koa-render?

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

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

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.

Named routes

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

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.

Reversed named route

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

Thanks

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 ๐Ÿ‘

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.

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

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);

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`

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?

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

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.

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.

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?

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'))

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....

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 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

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

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?

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.

path-to-regexp

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

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.

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)

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.

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.