0%

Hapi.jsでHappy Coding - Part3: プラグインをつくる

MongoDBへのCRUD操作とSwagger UIからAPIをテストするプロジェクトHapi.jsで作成しました。app.jsのRouteの処理が長くなったので、別ファイルに移動しようと思います。Hapi.jsではPluginsの仕組みで機能拡張ができます。Swaggerのインタフェースを提供するhapi-swaggerはnpmからパッケージをインストールしましたが、プラグインはアプリ内にも簡単に作ることができるのでRoute処理をプラグインにリファクタリングします。

公開されているプラグインはこちらのページに用途別にまとまっています。

プロジェクト

Routeのプラグインを作成したリポジトリはこちらです。ディレクトリは以下のようになっています。

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

今までと同様にDocker Composeを使いMongoDBとlinkしています。

~/node_apps/docker-hapi/docker-compose.yml
hapi:
build: .
ports:
- 3000:3000
volumes:
- .:/app
links:
- mongo
mongo:
image: mongo
volumes:
- ./mongo:/data/db

routes/jobs.js

routes/jobs.jsが作成したプラグインです。長くなるのでPOST以外は省略します。今までapp.jsに定義していたRouteの処理をexports.registerの関数内に移動しました。

~/node_apps/docker-hapi/routes/jobs.js
'use strict';
var Joi = require('joi');
var JobModel = require('../models/job');

exports.register = function(server, options, next) {

server.route({
method: 'POST',
path: '/api/jobs',
config: {
tags: ['api'],
description: 'Save job data',
notes: 'Save job data',
validate: {
payload: {
name: Joi.string().required(),
query: Joi.string().required()
}
}
},
handler: function(request, reply) {
var job = new JobModel(request.payload);
job.save(function(error) {
if(error) {
reply({
statusCode: 503,
message: error
});
} else {
reply({
statusCode: 201,
message: 'Job Saved Successfully'
});
}
});
}
});
...
// callback to complete
next();
}

exports.register.attributes = {
name: 'jobs-route'
}

重要なのは関数の最後にコールバックのnext()を実行してこのプラグインでの処理の終了を伝えることです。またexports.register.attributesにこのプラグインの名前を定義しておきます。

app.js

Routeの処理を別ファイルにプラグインとして移動したのでapp.jsの構成はすっきりと短くなりました。プラグインの登録はserver.registerを実行して行います。Swaggerのプラグインと加えて2つになったのでplugins配列に格納します。

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

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

mongoose.connect('mongodb://'+process.env.MONGO_PORT_27017_TCP_ADDR+':'
+process.env.MONGO_PORT_27017_TCP_PORT+'/jobdb');
server.connection({port: 3000});

var plugins = [
{ register: require('hapi-swagger'),
options: {
apiVersion: "0.0.1"
}
},
{ register: require('./routes/jobs')}
];

server.register(plugins, function(err){
if (err) throw err;
server.start(function (){
console.log('Server running at:', server.info.uri);
});
});

プログラムの実行

Docker Composeからhapiサービスを実行します。

$ docker-compose up hapi
Recreating dockerhapi_mongo_1...
Recreating dockerhapi_hapi_1...
Attaching to dockerhapi_hapi_1
hapi_1 |
hapi_1 | > docker-hapi@0.0.1 start /app
hapi_1 | > node app.js
hapi_1 |
hapi_1 | Server running at: http://803cef3ac3ca:3000

Routeをプラグイン化してもSwaggerUIからMongoDBへのCRUD処理はできるのでリファクタリングは成功です。

hapi-plugin.png