Node.jsでAPIを作るときのフレームワークに何が良いかいろいろと試しています。Hapi.js、LoopBack、Salis.js、actionhero.jsと試してみました。Koaは以前から気になっていましたが、ちょっと難しい印象があって避けていました。しかしES6ことECMAScript 2015がいよいよ承認されました。もたもたしているとES7やES8が来てしますので、もうクライアント側もサーバー側もES6に移行していかないといけないです。
ES6
ES6について全くの初心者なのですが、幸せになれそうな予感がするのでベットしようと思います。
ES6とio.js
サーバーサイドでES6やKoaを使う場合、io.jsの方が対応が進んでいます。そもそもio.jsが設立した原因の一つにNode.jsのV8とES6対応の開発方針への不満があったようです。ただ日本のNode.jsの広まりを考えるとサーバーサイドの開発言語としての採用に混乱を招いているようであまり良いことではありません。もっともio.jsがNode Foundationへの参加を決定して今後統合されていくみたいですが。
ES6と関数型プログラミング
言語仕様としてlet
やconst
などで変数のスコープが安全に書けたり、パターンマッチングによる分配束縛(Destructuring)も使えます。
ようやくasyncとif (error) return callback(error)
のようなError-First Callbackに慣れてきた程度なのですが、ES6だともっとエレガントににコールバック地獄から抜けられるそうです。GeneratorやPromiseなどまだ理解が必要なことが多いです。
またlodashを覚えてからNode.jsでも関数型プログラミング風に書けて読みやすくなりました。ES6ではArrow Functionsが標準で使えるので無名関数がもっと短く書けるようになります。
Destructuring、Arrow Function、Generator、Promiseを日本語に訳したりカタカナで表記するのも適切か悩むようになりました。明治時代の新漢語みたいにセンスある日本語ができれば良いのですが、そういう時代でもないですし。
Dockerでio.js環境をつくる
Dockerにはio.jsのiojsのオフィシャルイメージがあります。GitHubのリポジトリはdocker-iojsです。バージョンは6月にリリースされたばかりの2.3.0も用意されています。
Node.jsのオフィシャルイメージからONBUILD版を使うときは以下のように書いていました。
FROM node:0.12-onbuild
EXPOSE 3000
io.jsでも同じようにONBUILD版があります。
FROM iojs:2.3-onbuild
EXPOSE 3000
ExpressでHello World
io.jsでKoaのプログラムを書く前に、お約束のExpressでHello Worldを動かしてみます。
プロジェクト
プロジェクトのディレクトリは以下のようになります。
$ cd ~/node_apps/docker_iojs
$ tree
.
├── Dockerfile
├── app.js
├── docker-compose.yml
└── package.json
app.jsはExpressのHello Worldを使います。
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
{
"name": "iojs-express",
"description": "iojs-express",
"version": "0.0.1",
"private": true,
"dependencies": {
"express": "^4.13.0"
},
"scripts": {
"start": "node app.js"
}
}
Dockerfileのベースイメージはiojs:2.3-onbuildを使います。
FROM iojs:2.3-onbuild
MAINTAINER Masato Shimizu <ma6ato@gmail.com>
EXPOSE 3000
docker-compose.ymlを記述します。ONBUILDを使っているのでカレントディレクトリはコンテナにマップしません。マウントするとカレントディレクトリにはDockerfileでnpm install
したnode_modules
が隠れてしまいます。
express:
build: .
volumes:
- /etc/localtime:/etc/localtime:ro
ports:
- "3030:3000"
実行
Dockerイメージをビルドしてコンテナを起動します。io.jsでもコマンドはnodeコマンドです。バージョンは2.3.0
です。Node.jsの方は同じnodeコマンドでも0.12.4
なので混乱しそうです。
$ docker-compose build
$ docker-compose up
Creating dockeriojs_express_1...
Attaching to dockeriojs_express_1
express_1 | npm info it worked if it ends with ok
express_1 | npm info using npm@2.11.1
express_1 | npm info using node@v2.3.0
express_1 | npm info prestart iojs-express@0.0.1
express_1 | npm info start iojs-express@0.0.1
express_1 |
express_1 | > iojs-express@0.0.1 start /usr/src/app
express_1 | > node app.js
express_1 |
express_1 | Example app listening at http://:::3000
psで見るとDockerホストの3030ポートにマップされています。
docker-compose ps
Name Command State Ports
-----------------------------------------------------------------
dockeriojs_express_1 npm start Up 0.0.0.0:3030->3000/tcp
Docckerホストからcurlコマンドを使ってExpressの起動が確認できました。
$ curl localhost:3030
Hello World!