0%

Hapi.jsでHappy Coding - Part1: ルーティングとSwaggerプラグイン

Node.jsでREST APIを作成するフレームワークを調べていますがHapi.jsが良い感じです。いくつかチュートリアルで基本的な操作を勉強していきます。プラグインで機能を拡張することができるためベースはとても小さくできています。Swaggerのプラグインがあったので使ってみます。ただしLoopBackと違いメタデータを自分で定義する必要があります。

プロジェクト

今回作成するプロジェクトのディレクトリ構成です。ソースコードはリポジトリswaggerタグでpushしています。

$ cd ~/node_apps/docker-hapi
$ tree -L 1
.
├── Dockerfile
├── app.js
├── docker-compose.yml
├── mongo
├── node_modules -> /dist/node_modules
├── npm-debug.log
└── package.json

docker-compose.ymlのmongoサービスでdataディレクトリをカレントにマウントしています。mongoディレクトリの所有はrootになるのでbuild時にエラーになります。MongoDBのデータディレクトリをDockerイメージに追加しないように、.dockerignoreに追加して無視します。

~/node_apps/docker-hapi/.dockerignore
mongo

今回使うHapi.jsのプラグインのhapi-swaggerがNode.jsのバージョンに0.10.xを指定しているためベースイメージもこれにあわせます。

"engines": {
"node": "0.10.x"
},

これからこのプロジェクトでHapi.jsのプラグインとMongoDBを使ったサンプルを書いていこうと思います。

{
"name": "docker-hapi",
"description": "node-static app",
"version": "0.0.1",
"private": true,
"dependencies": {
"hapi": "^8.6.1",
"hapi-swagger": "^0.7.3",
"good-console": "^5.0.2",
"joi": "^6.4.3",
"mongoose": "^4.0.4"
},
"scripts": {"start": "node app.js"}
}

ルーティング

SinatraやExpressと同じようにルーティングはHTTPメソッドとURLのパターンで構成します。

Hello World

やはり最初は公式のGetting Startedから始めます。写経して感じをつかむのには丁度良い長さです。定番のHello Worldをapp.jsに実装します。

~/node_apps/docker-hapi/app.js
'user strict';

var Hapi = require('hapi'),
server = new Hapi.Server();

server.connection({port: 3000});

server.route({
method: 'GET',
path: '/{name}',
handler: function(request, reply) {
reply('Hello, ' + encodeURIComponent(request.params.name));
}
});

server.start(function() {
console.log('Server running at:', server.info.uri);
});

app.jsにパラメータ付きのpathでGETメソッドのRouteを1つ定義しています。URLのパラメーターはpathに定義したnameにバインドされて、request.params.nameの変数に格納されます。

$ curl -X GET localhost:3000/masato
Hello, masato

JSON

次はBuild RESTful API Using Node and Hapiを参考にしながらHapi.jsの使い方を勉強していきます。

app.jsに静的なJSONを返すRouteを追加します。APIの追加はmethod、path、handlerを追加していくのが基本的なコードになります。

~/node_apps/docker-hapi/app.js
....
server.route({
method: 'GET',
path: '/api/jobs',
handler: function(request, reply) {
reply({
statusCode: 200,
message: 'List all jobs',
data: [
{
name: 'Daily BABYMETAL',
query: 'babymetal'
},{
nama: 'Hourly Android',
query: 'android'
}
]
});
}
});
...

作成したRouteのpathをcurlでGETします。handlerでreplyしたJSONが返ります。

$ curl -X GET localhost:3000/api/jobs
{"statusCode":200,"message":"List all jobs","data":[{"name":"Daily BABYMETAL","query":"babymetal"},{"nama":"Hourly Andrond","query":"android"}]}

プラグイン

Swagger

Hapi.jsはプラグインを追加することで認証やAPIドキュメントなどの機能を追加していくことができます。
registerメソッドを使ってプラグインを追加します。

~/node_apps/docker-hapi/app.js
...
server.register({
register: require('hapi-swagger'),
options: {
apiVersion: "0.0.1"
}
}, function(err){
if(err) {
server.log(['error'], 'hapi-swagger load error: ' + err)
} else {
server.log(['start'], 'hapi-swagger interface loaded')
}
});
...

SwaggerでAPIドキュメントを作成するため、RouteにSwagger用のconfigを追加します。tagsは必須項目になっています。

~/node_apps/docker-hapi/app.js
...
server.route({
method: 'GET',
path: '/api/jobs',
config: {
tags: ['api'],
description: 'List all jobs',
notes: 'List all jobs'
},
...

Docker Composeをupします。

$ docker-compose up

/documentationをブラウザで開くとSwagger UIが使えるようになります。

http://xxx.xxx.xxx:3000/documentation

swagger.png