Skip to content

Commit

Permalink
Default router middleware without path to root.
Browse files Browse the repository at this point in the history
- Fixes #161, fixes #155, fixes #156.
- Removes dependency on koa-compose.
  • Loading branch information
alexmingoia committed Sep 26, 2015
1 parent 7b1b917 commit 883c1af
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 165 deletions.
73 changes: 22 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ npm install koa-router
```

## API Reference

* [koa-router](#module_koa-router)
* [Router](#exp_module_koa-router--Router)
* [new Router([opts])](#new_module_koa-router--Router_new)
* _instance_
* [.get|put|post|patch|delete](#module_koa-router--Router+get|put|post|patch|delete) ⇒ <code>Router</code>
* [.routes](#module_koa-router--Router+routes) ⇒ <code>function</code>
* [.use([path], middleware, [...])](#module_koa-router--Router+use) ⇒ <code>Router</code>
* [.prefix(prefix)](#module_koa-router--Router+prefix) ⇒ <code>Router</code>
* [.allowedMethods([options])](#module_koa-router--Router+allowedMethods) ⇒ <code>function</code>
* [.redirect(source, destination, code)](#module_koa-router--Router+redirect) ⇒ <code>Router</code>
* [.route(name)](#module_koa-router--Router+route) ⇒ <code>Layer</code> &#124; <code>false</code>
Expand All @@ -41,7 +40,7 @@ npm install koa-router

<a name="exp_module_koa-router--Router"></a>
### Router ⏏
**Kind**: Exported class
**Kind**: Exported class
<a name="new_module_koa-router--Router_new"></a>
#### new Router([opts])
Create a new router.
Expand All @@ -50,9 +49,8 @@ Create a new router.
| Param | Type | Description |
| --- | --- | --- |
| [opts] | <code>Object</code> | |
| [opts.prefix] | <code>String</code> | prefix router paths |

**Example**
**Example**
Basic usage:

```javascript
Expand Down Expand Up @@ -142,19 +140,6 @@ forums.use('/forums/:fid/posts', posts.routes());
app.use(forums.routes());
```

#### Router prefixes

Route paths can be prefixed at the router level:

```javascript
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`.
Expand Down Expand Up @@ -190,7 +175,7 @@ router
// /users/3/friends => [{"id": 4, "name": "TJ"}]
```

**Kind**: instance property of <code>[Router](#exp_module_koa-router--Router)</code>
**Kind**: instance property of <code>[Router](#exp_module_koa-router--Router)</code>

| Param | Type | Description |
| --- | --- | --- |
Expand All @@ -202,23 +187,23 @@ router
#### router.routes ⇒ <code>function</code>
Returns router middleware which dispatches a route matching the request.

**Kind**: instance property of <code>[Router](#exp_module_koa-router--Router)</code>
**Kind**: instance property of <code>[Router](#exp_module_koa-router--Router)</code>
<a name="module_koa-router--Router+use"></a>
#### router.use([path], middleware, [...]) ⇒ <code>Router</code>
Use given middleware(s) before route callback.

Only runs if any route is matched. If a path is given, the middleware will
run for any routes that include that path.

**Kind**: instance method of <code>[Router](#exp_module_koa-router--Router)</code>
**Kind**: instance method of <code>[Router](#exp_module_koa-router--Router)</code>

| Param | Type |
| --- | --- |
| [path] | <code>String</code> |
| middleware | <code>function</code> |
| [...] | <code>function</code> |
| [path] | <code>String</code> |
| middleware | <code>function</code> |
| [...] | <code>function</code> |

**Example**
**Example**
```javascript
router.use(session(), authorize());

Expand All @@ -227,34 +212,20 @@ router.use('/users', userAuth());

app.use(router.routes());
```
<a name="module_koa-router--Router+prefix"></a>
#### router.prefix(prefix) ⇒ <code>Router</code>
Set the path prefix for a Router instance that was already initialized.

**Kind**: instance method of <code>[Router](#exp_module_koa-router--Router)</code>

| Param | Type |
| --- | --- |
| prefix | <code>String</code> |

**Example**
```javascript
router.prefix('/things/:thing_id')
```
<a name="module_koa-router--Router+allowedMethods"></a>
#### router.allowedMethods([options]) ⇒ <code>function</code>
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 <code>[Router](#exp_module_koa-router--Router)</code>
**Kind**: instance method of <code>[Router](#exp_module_koa-router--Router)</code>

| Param | Type | Description |
| --- | --- | --- |
| [options] | <code>Object</code> | |
| [options.throw] | <code>Boolean</code> | throw error instead of setting status and header |

**Example**
**Example**
```javascript
var app = koa();
var router = router();
Expand All @@ -281,7 +252,7 @@ router.all('/login', function *() {
});
```

**Kind**: instance method of <code>[Router](#exp_module_koa-router--Router)</code>
**Kind**: instance method of <code>[Router](#exp_module_koa-router--Router)</code>

| Param | Type | Description |
| --- | --- | --- |
Expand All @@ -293,11 +264,11 @@ router.all('/login', function *() {
#### router.route(name) ⇒ <code>Layer</code> &#124; <code>false</code>
Lookup route with given `name`.

**Kind**: instance method of <code>[Router](#exp_module_koa-router--Router)</code>
**Kind**: instance method of <code>[Router](#exp_module_koa-router--Router)</code>

| Param | Type |
| --- | --- |
| name | <code>String</code> |
| name | <code>String</code> |

<a name="module_koa-router--Router+url"></a>
#### router.url(name, params) ⇒ <code>String</code> &#124; <code>Error</code>
Expand All @@ -316,7 +287,7 @@ router.url('user', { id: 3 });
// => "/users/3"
```

**Kind**: instance method of <code>[Router](#exp_module_koa-router--Router)</code>
**Kind**: instance method of <code>[Router](#exp_module_koa-router--Router)</code>

| Param | Type | Description |
| --- | --- | --- |
Expand All @@ -328,14 +299,14 @@ router.url('user', { id: 3 });
Run middleware for named route parameters. Useful for auto-loading or
validation.

**Kind**: instance method of <code>[Router](#exp_module_koa-router--Router)</code>
**Kind**: instance method of <code>[Router](#exp_module_koa-router--Router)</code>

| Param | Type |
| --- | --- |
| param | <code>String</code> |
| middleware | <code>function</code> |
| param | <code>String</code> |
| middleware | <code>function</code> |

**Example**
**Example**
```javascript
router
.param('user', function *(id, next) {
Expand All @@ -356,14 +327,14 @@ router
#### Router.url(path, params) ⇒ <code>String</code>
Generate URL from url pattern and given `params`.

**Kind**: static method of <code>[Router](#exp_module_koa-router--Router)</code>
**Kind**: static method of <code>[Router](#exp_module_koa-router--Router)</code>

| Param | Type | Description |
| --- | --- | --- |
| path | <code>String</code> | url pattern |
| params | <code>Object</code> | url parameters |

**Example**
**Example**
```javascript
var url = Router.url('/users/:id', {id: 1});
// => "/users/1"
Expand Down
66 changes: 30 additions & 36 deletions lib/layer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
var compose = require('koa-compose');
var debug = require('debug')('koa-router');
var pathToRegExp = require('path-to-regexp');

Expand All @@ -23,10 +22,7 @@ function Layer(path, methods, middleware, opts) {
this.name = this.opts.name || null;
this.methods = [];
this.paramNames = [];
this.fns = {
params: {},
middleware: []
};
this.stack = Array.isArray(middleware) ? middleware : [middleware];

methods.forEach(function(method) {
var l = this.methods.push(method.toUpperCase());
Expand All @@ -35,12 +31,8 @@ function Layer(path, methods, middleware, opts) {
}
}, this);

if (!Array.isArray(middleware)) {
middleware = [middleware];
}

// ensure middleware is a function
middleware.forEach(function(fn) {
this.stack.forEach(function(fn) {
var type = (typeof fn);
if (type !== 'function') {
throw new Error(
Expand All @@ -50,19 +42,10 @@ function Layer(path, methods, middleware, opts) {
}
}, this);

this.fns.middleware = middleware;

if (middleware.length > 1) {
this.middleware = compose(middleware);
}
else {
this.middleware = middleware[0];
}

this.path = path;
this.regexp = pathToRegExp(path, this.paramNames, this.opts);

debug('defined route %s %s', this.methods, this.opts.prefix+this.path);
debug('defined route %s %s', this.methods, this.opts.prefix + this.path);
};

/**
Expand Down Expand Up @@ -179,20 +162,35 @@ Layer.prototype.url = function (params) {
*/

Layer.prototype.param = function (param, fn) {
var middleware = [];

this.fns.params[param] = function *(next) {
var stack = this.stack;
var params = this.paramNames;
var middleware = function *(next) {
yield *fn.call(this, this.params[param], next);
};

this.paramNames.forEach(function(param) {
var fn = this.fns.params[param.name];
if (fn) {
middleware.push(fn);
middleware.param = param;

params.forEach(function (p, i) {
var prev = params[i - 1];

if (param === p.name) {
// insert param middleware in order params appear in path
if (prev) {
if (!stack.some(function (m, i) {
if (m.param === prev.name) {
return stack.splice(i, 0, middleware);
}
})) {
stack.some(function (m, i) {
if (!m.param) {
return stack.splice(i, 0, middleware);
}
});
}
} else {
stack.unshift(middleware);
}
}
}, this);

this.middleware = compose(middleware.concat(this.fns.middleware));
});

return this;
};
Expand All @@ -207,11 +205,7 @@ Layer.prototype.param = function (param, fn) {

Layer.prototype.setPrefix = function (prefix) {
if (this.path) {
if (this.opts.rootMiddleware) {
this.path = prefix;
} else {
this.path = prefix + this.path;
}
this.path = prefix + this.path;
this.paramNames = [];
this.regexp = pathToRegExp(this.path, this.paramNames, this.opts);
}
Expand Down
Loading

0 comments on commit 883c1af

Please sign in to comment.