なっく日報

技術やら生活やらのメモ

expressでkoa.js的な感じに書く方法

koa.jsがあるので、世の中で需要があるかわかりませんが、そういう方法もあるというご紹介。

generatorを使って、同期風に書く方法があるかというお話です。

方法1

co-expressを使う。 github.com

こんな感じでソースが書けます。

var fs = require('mz/fs');
var express = require('express');
var wrap = require('co-express');

var app = express();

app.get('/', wrap(function* (req, res) {
  var packageContents = yield fs.readFile('./package.json', 'utf8');
  res.send(packageContents);
}));

app.listen(8000);

なお、co-expressの実装はこれだけ。

var co = require('co');

module.exports = function wrap(gen) {
  var fn = co.wrap(gen);

  if (gen.length === 4) {
    return function(err, req, res, next) {
      return fn(err, req, res, next).catch(next);
    }
  }

  return function(req, res, next) {
    return fn(req, res, next).catch(next);
  };
};

方法2

co-expressの実装を参考に自前で書きます。
速度が気になる人はbluebirdのcoroutineを使う方がいいかもしれません。

bluebirdjs.com

Benchmarks | bluebirdによれば、tj/coより3倍とかそんなレベルで早いそう。

'use strict';
const Promise = require('bluebird');

module.exports = function wrap(gen) {
  const fn = Promise.coroutine(gen);

  if (gen.length === 4) {
    return (err, req, res, next) =>
      fn(err, req, res, next).catch(next);
  }

  return (req, res, next) =>
    fn(req, res, next).catch(next);
};

こんな感じ?

まとめ

意外と簡単。