# koa-next

a simple encapsulation for koa2, you can use it to build your minimal web server. 

[![npm version](https://badge.fury.io/js/koa-next.svg)](https://badge.fury.io/js/koa-next)

## installation

```$ npm install koa-next --save```

make sure your node version > *7.6.0*

## start a server

```js
const koa = require('koa-next');
const path = require('path');
 
koa({
  watch: true, // to make auto-reload, default false
  base: __dirname, // base dir
  path: {
    middleware: path.join(__dirname, 'middleware'), // middleware folder
    controller: path.join(__dirname, 'controller'), // controller folder
    service: path.join(__dirname, 'service') //service folder
  }
}).start();
```

## what are middleware controller & service ?

The diff between koa-next & koa2 is koa-next uses three-type handlers to make our coding happier.

### middleware 

just the same as the koa's [middleware](https://github.com/koajs/koa/blob/master/docs/guide.md#writing-middleware)

every request will pass all the middlewares set here. u can add logger, login and other handle request funs here. ex,

```js
module.exports = async function m1 (ctx, next) {
  logger.info(`path is ${ctx.path}`);
  await next();
}
```

every request will log due to this middleware. of course, it must under the `middleware` folder.


### controller

you can set your handlers to handle specific path request, ex, suppose below is the `profile.js` under `controller` folder.

```js
module.exports = [
  {
    method: 'get',
    url: '/profile/:name',
    controller: async (ctx) => {
      ctx.body = `u are visiting ${ctx.params.name} home page`;
    }
  },
  {
    method: 'post',
    url: '/profile/annoymous',
    controller: async (ctx) => {
      ctx.body = `not found this person`;
    }
  }
];
```

when u visit `/profile/pony`, u can get 'u are visiting pony home page' on your browser, and visit '/profile/annoymous', 'not found this person' comes.

koa-next will pass the params at ctx.params, just as `:name` above.

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

- `string` - ex `/post`

- `string|string` - `|` separated strings, ex `/post|page`

- `:name` - Wildcard route matched to a name

- `(regex)` - A regular expression match without saving the parameter (not recommended)

- `:name(regex)` - Named regular expression match


### service

you can set it to add fun at ctx. ex,

```js
module.exports = function (ctx) {
  return {
    json(data) {
      ctx.type = 'application/json';
      ctx.body = JSON.stringify(data, null, 2);
    }
  };
};
``` 

suppose the fileName of this code is `simpleResponse.js` under the `service` folder.

u can use this at your controller, ex,

```js
  {
    url: '/profile/annoymous',
    controller: async (ctx) => {
      await ctx.simpleResponse.json({user: 'annoymous'});
    }
  }
``` 

when u are visting `/profile/annoymous`, u will set the json type response quickly.

## tips

1. every time you modify your services, middlewares and controllers, koa-next will auto-reload without restart, have fun.

2. u can add `$config.js` under `middleware` folder to custom your middlewares' invoke order, ex,
```js
module.exports = {
  order: ['m2.js', 'm1.js'],
  except: ['m4.js']
}
```
the `m2.js` will be ahead of `m1.js` at every request, and `m4.js` will be not invoked.

3. u can set specific middlewares for one controller, add `middlewares` property at your controller. ex, if u wanna to get a body content from POST method, u can add `koa-body` middleware at this controller.

```js
{
  url: '/',
  method: post,
  middlewares: requre('koa-body')({formidable:{uploadDir: __dirname}}), 
  controller: async (ctx) => {
    console.log(ctx.request.body);
  }
}
```

these middlewares only impact this controller.

4. u can also add middlewares at your config, ex,
```js

koa-next({
  middleware | middlewares: Function | Function <Array> 
})
```


5. u can use handlebars at your service like example.

## tl;dr

see `/example` to start it.

## see also

[koa2](https://www.npmjs.com/package/koa)

[routington](https://www.npmjs.com/package/routington)

[trie](https://en.wikipedia.org/wiki/Trie)

[koa-body](https://www.npmjs.com/package/koa-body)
