105
106

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Node.jsAdvent Calendar 2015

Day 15

そろそろkoa入門

Last updated at Posted at 2015-12-15

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

koa.jsとは

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

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

以下はhello worldです。

app.js

'use strict';

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

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

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

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で書くと

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

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

Cookie

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

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

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

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

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

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

Routing

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

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

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.jsonjadeがあればjadeを読み込んでくれるようになります。

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

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でディレクトリを作成してその中にテンプレートを作成します。

layout.jade
doctype html
html
  head
    title= title
  body
    block body
index.jade
extends layout

block body
  h1= title
  a(href="/users/k2wanko") k2wanko
user.jade
extends layout

block body
  h1 Hello #{user.name}!

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

Error Handling

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

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

Stream

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

まとめ

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

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

105
106
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
105
106

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?