そろそろkoa入門

koa.jsの出た当初はexpress.jsのほうが機能が優れていてあんまりやるぞーって気になってなかったのですが、
ネタ探しに調べてたら既にメジャーバージョンも出ているし
パッケージも豊富になっていたので
そろそろ大丈夫じゃないかなと思ったのでkoa.jsやってみます。

# koa.jsとは

Node.jsの新しいWebFrameworkです。Node.jsのWebFrameworkといえばexpress.jsが有名ですがその開発メンバーが開発しているフレームワークです。

koaはgeneratorを使うことでコールバックをなくしエラーハンドリングが強化されています。

以下はhello worldです。

```js:app.js

'use strict';

const koa = require('koa');
const app = module.exports = koa();

app.use(function *(){
    this.body = 'Hello world';
});
```

これだけでは、ありがたみがわかりませんが以下の様なコードだともう少しわかりやすくなります。

```js:app.js
'use strict'; 

const koa = require('koa');
const request = require('request-promise');
const app = module.exports = koa();

app.use(function *(){
    let options = {
        uri: 'https://github.com' + this.request.url
    };

    this.body = yield request(options);
});
```

これをexpressで書くと

```js:app.js
app.get('/', function(req, res){
  ...
  request(options).
    then(function(body){
      res.send(body);
    }).
    catche(...);
});
```

みたくPromiseを使ってもコールバックが２つはできてしまいます。
koaのほうが見通しのよいコードを書けます。

# Cookie

Cookieの設定方法です。`this.cookies`を使います。

```js:app.js
'use strict'; 

const koa = require('koa');
const app = module.exports = koa();

app.use(function *(){
    let count = ~~this.cookies.get('count') + 1;
    this.cookies.set('count', count);
    this.body = 'count: ' + count;
});
```

特に解説することもなく普通に使えますね。
署名もサポートされています。

```js
app.keys = ['im a newer secret', 'i like corgi'];
```

setする時は次のような感じです。

```js
this.cookies.set('name', 'koki_cheese', { signed: true });
```

# Routing

ルーティングなどもMiddlewareとして別パッケージに分離されています。
この辺はexpress.jsもv4からそんな感じですね

ルーティングには`koa-route`を使います

```js:app.js
'use strict'; 

const koa = require('koa');
const _ = require('koa-route');
const app = module.exports = koa();

app.
    use(_.get('/', function *(){
        this.body = 'Hello world';
    })).
    use(_.get('/users/:name', function *(name){
        this.body = 'Hello, ' + name + '!';
    }));
```

# Templates

テンプレートエンジンを利用するのに`co-views`を使います。
テンプレートエンジンは`jade`を使います

`package.json`に`jade`があれば`jade`を読み込んでくれるようになります。

`npm install --save co-views jade`でインストールすると使えるようになります。

```js:app.js
'use strict'; 

const koa = require('koa');
const _ = require('koa-route');
const views = require('co-views');
const app = module.exports = koa();

let render = views(__dirname + '/views', { ext: 'jade'});

let title = 'koa-example';

app.
    use(_.get('/', function *(){
        this.body = yield render('index', {
            title: title
        });
    })).
    use(_.get('/users/:name', function *(name){
        this.body = yield render('user', {
            title: name + ' - ' + title,
            user: {
                name: name
            }
        });
    }));
```

app.jsと同じ位置にviewsでディレクトリを作成してその中にテンプレートを作成します。

```jade:layout.jade
doctype html
html
  head
    title= title
  body
    block body
```

```jade:index.jade
extends layout

block body
  h1= title
  a(href="/users/k2wanko") k2wanko
```

```jade:user.jade
extends layout

block body
  h1 Hello #{user.name}!
```

という感じでレイアウトを書いてあげればHTMLの表示もらくらくできます。

# Error Handling

エラーはイベントで通知されます。
この辺はNode.jsではおなじみですね。

```js
app.on('error', function(err){
  log.error('server error', err);
});
```

# Stream

すみません　時間がなくて試せなかったので詳しくは書けませんでした。
この辺のサンプルを参考にしたかったのですが僕自身まだStreamを制しきれてないので時間が掛かってしまいました。

- https://github.com/koajs/examples/tree/master/stream-view
- https://github.com/koajs/examples/tree/master/stream-file
- https://github.com/koajs/examples/tree/master/stream-objects
- https://github.com/koajs/examples/tree/master/stream-server-side-events

# まとめ

コードは https://github.com/k2wanko/koa-example においています。
Node.js v5.1.1で試しました。

感想としては、機能面でもexpressに劣らないくらい色々充実してて良さそうだし
何かあっても本体はシンプルだし足りない機能は自分で簡単に作れそうです
あと一番はコードの見通しがよくなるのは最高ですね。