いまさらkoa.js入門


nanameue,incでインターン中の斎藤です。

最近JSばっかりでkoa.jsにまで手を出してしまったのでkoa.jsの入門記事を書きます。
個人的には1年半ほどRailsをいじっていたのですがReactからJS界隈に入り始め、ついにバックエンドまで到達しました。

Rails界隈と比較すると割とミニマムな物が好まれていて、高機能なものよりシンプルな部品を組み合わせて作っていく感じです。

Railsのあまりの大きさに嫌気がさしRailsからnode系に移った人も多いらしくRailsを真似たsailsというフレームワークもありますが全く流行ってません。

自分は1週間ほど前からkoa.jsをやり始めたのですが、yieldとかgenerateなどを使っているので理解するのに時間がかかりました。なのでその部分を解説します。多分ここがkoaの本質でkoa自体はスーパーミニマムなので多分ここを理解すればkoa自体を理解したことになるんじゃないでしょうか。ならないか。

koa.js

koa自体はすごく小さくルーターさえも提供されていません。koaが提供しているのは単なるミドルウェアです。

というわけでkoaの公式サイトのsampleコードをやっていこうとしたのですがいきなりこんな感じのコードが出てきて意味不明になりました。

// x-response-time
app.use(function *(next){
  var start = new Date;
  yield next;
  var ms = new Date - start;
  this.set('X-Response-Time', ms + 'ms');
});

// logger
app.use(function *(next){
  var start = new Date;
  yield next;
  var ms = new Date - start;
  console.log('%s %s - %s', this.method, this.url, ms);
});

一つずつ解説するとfunction *()というのはジェネレーター関数と言って簡単に言うとコードを実行するとyieldでストップします。es6の新機能です。上のコードではx-response-time実行中にyieldでストップしnextにloggerのコードが代入されて実行されます。ジェネレーター関数では.next()とかで次に進めるんですがそういうのはkoaがうまくやってくれてるんだと思います。

co

app.use(function *(){
this.state.user = yield User.find(id);
});

上のコードはUser.find(id)でユーザーが見つかり次第this.state.userへ代入してくれます。なぜこのような同期処理が可能かというとkoa自体はcoというライブラリを組み込んでいてそのcoの機能で可能になります。

coは一言で言えばPromiseをyieldの引数に取りPromiseがresolveして返した値をreturnしてくれます。意味不明ですよね。なので下にサンプルコードをのせました。他にもPromiseを含む配列を引数にしたりオブジェクトを引数にしたりできます。まぁでも本質はPromiseをいい感じに同期処理っぽく書けるということです。

例えばmongooseのfindOneメソッド。

var query = User.findOne({name: "Guns N' Roses"});
 // A query is not a fully-fledged promise, but it does have a `.then()`.
 query.then(function (user) {
   this.state.user = user
 })

findOneの返り値はPromiseではないですがthenなどを使えPromiseのような働きをします。なのでこれもkoaのyieldで使用できます。下のコードは上のコードと同等な働きをします。

 this.state.user = yield User.findOne({name: "Guns N' Roses"});

this.state.userにユーザー情報が代入されます。こんな感じで綺麗に書けるんですよね。そんだけです。

いきなりですが以上でkoaの説明は終わりです。でもここら辺が一番トリッキーなのでここら辺を理解すれば、あとはkoaの公式サイトを読んだりチュートリアルとかをすればなんとか行けるじゃないでしょうか。koa楽しいですよ。プログラムしてる感じがします。下にオススメチュートリアルのリンクを貼っておきます。

おすすめチュートリアルリスト

Introduction to Generators & Koa.js: Part 1

Introduction to Generators & Koa.js: Part 2

A Simple CRUD Demo with Koa.js