LoginSignup
9
8

More than 5 years have passed since last update.

Hapi.jsでHappy Coding - Part2: MongoDBとSwaggerのCRUD

Last updated at Posted at 2015-06-12

前回に続いてBuild RESTful API Using Node and Hapiのチュートリアルを読みながらMongoDBを使ったCRUDの実装を勉強していきます。リポジトリはこちらにpushしています。

プロジェクト

前回作成したプロジェクトにmodelを追加しました。

$ tree
.
├── Dockerfile
├── app.js
├── docker-compose.yml
├── models
│   └── job.js
├── mongo
├── node_modules -> /dist/node_modules
└── package.json

MongoDBサービス

docker-compose.ymlにMongoDBサービスを追加します。データのディレクトリはDockerホストにマウントして開発中は気軽にコンテナの破棄をできるようにしました。

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

カレントディレクトリにrootユーザーが所有するmongoディレクトリができるので、Dockerの管理外にします。

.dockerignore
mongo

Mongooseとjoi

MongoDBにアクセスするためにMongooseを使います。MongoDBはスキーマレスですがMongooseはスキーマを定義します。JSONにスキーマを持たせてある程度きっちりレコードを管理したい場合、フォームのバリデーションライブラリのjoiと併せて使うと煩雑になりがちなコードが宣言型ですっきりします。

app.js
'use strict';

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

mongoose.connect('mongodb://'+process.env.MONGO_PORT_27017_TCP_ADDR+':'
              +process.env.MONGO_PORT_27017_TCP_PORT+'/jobdb');

var JobModel = require('./models/job');

server.connection({port: 3000});

以下のようなモデルのスキーマを定義します。Hapi.jsはagendaのフロントに使う予定なのでジョブのモデルを作りました。

models/job.js
'use strict';

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var JobSchema = new Schema({
    name: String,
    query: String
});

module.exports = mongoose.model('Job', JobSchema);

CRUD

LoopBackの場合ジェネレーターのおかげでコードを書かなくてもCRUDの操作が実装できます。今回のHapi.jsのサンプルはスカッフォールディングで十分なくらい単純ですが、Mongooseとjoiを使ったリクエストパラメーターの扱いを理解すればサクサク実装できそうな気がします。

POST /api/jobs

POSTメソッドを例にします。tags: ['api']はSwagger用に必須項目になります。モデル保存後のコールバックは冗長な感じです。pyramid of doom.

app.js
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'
                });
            }
        });
    }
});

Swaggerの起動

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

$ 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://22fb2b92f597:3000

ブラウザでSwagger UIを表示します。CRUD処理のAPIの動くドキュメントが簡単に作成できました。

swagger-crud.png

9
8
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
9
8