1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

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

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?