連日似たような投稿ばかりですみません…。
以前、こんな投稿をしました。
この記事は↑の2つを混ぜつつ、実際に動くレベルまで持っていた記録になります。
つまり、RethinkDBへの操作をORMのThinkyでカンタンに行いつつ、Expressを使ってRESTfulなWebAPI化しました。
ソースコードだけみたい、という方はこちらにアップしてあります。
前提条件
RethinkDBをインストールして、ローカルで立ち上げておいてください。
MacOSの方はhomebrewからどうぞ。
$ brew update && brew install rethinkdb
$ rethinkdb # 立ち上げ
セット・アップ
必要なパッケージをインストールします。
$ npm init -y
$ npm install --save express thinky body-parser
package.jsonはだいたいこんな感じ。
{
"name": "express-thinky-api",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"body-parser": "^1.15.2",
"express": "^4.14.0",
"thinky": "^2.3.6"
}
}
リアルタイムWebAPI作成
ここからは、コードを書いてリアルタイムWebAPIを作っていきます。
Thinky初期化
まずは、thinkyを初期化します。その際に、オブジェクトでセット・アップ情報を渡します。
// ./thinky.js
var thinky = require('thinky')({
host: 'localhost',
port: 28015,
db: 'People'
})
module.exports = thinky
スキーマ定義
まずは、操作対象となるモデルを作成します。
Node.jsからRethinkDBを操作するthinkyをrequireします。
// ./schema.js
const thinky = require('./thinky')
var r = thinky.r
var People = thinky.createModel('People', {
firstName: String,
lastName: String,
coolnessFactor: Number,
date: { _type: Date, default: r.now() }
})
People.ensureIndex('date')
module.exports = People
Peopleという名前でモデルを生成しました。
Thinkyの使い方については、以下の記事をご覧ください。
node.jsでRethinkDBを扱うためのORM "Thinky" を試してみた
リアルタイム化
RethinkDBの特徴はリアルタイム性です。ここでは、Peopleモデルに対して、リアルタイムロギング機能を付け加えます。
// ./realtime.js
const stringify = (doc) => {
return JSON.stringify(doc, null, 2)
}
const realtimeLogging = (Model) => {
Model.changes().then((feed) => {
feed.each((err, doc) => {
if (err) {
console.log(err)
process.exit(1)
}
if (doc.isSaved() === false) {
console.log("The following document was deleted:")
console.log(stringify(doc))
} else if (doc.getOldValue() === null) {
console.log("A new document was inserted:")
console.log(stringify(doc))
} else {
console.log("A document was updated.")
console.log(stringify(doc.getOldValue()))
console.log("New value:")
console.log(stringify(doc))
}
})
}).error((err) => {
console.log(err)
process.exit(1)
})
}
module.exports = realtimeLogging
ちょっと長くなりましたが、ここでやっていることは以下のとおりです。
- リアルタイム ロギング関数の定義
- changesメソッドを使って、変更を監視(データの作成・削除・更新がフックになります)
- 変更のあったドキュメント(いわゆるRow)をログ出力
API作成
APIを作成します。ここでは、ルーティングに応じて呼ばれる関数を定義します。
'use strict'
const thinky = require('./thinky')
const r = thinky.r
const People = require('./schema')
// 一覧取得
exports.list = function (req, res) {
People.orderBy({ index: r.desc('date') }).run().then((people) => {
res.json(people)
}).error((err) => {
res.json({ message: err })
})
}
// 作成
exports.add = function (req, res) {
var person = new People(req.body)
person.save().then((result) => {
res.json(result)
}).error((err) => {
res.json({ message: err })
})
}
// 取得
exports.get = function (req, res) {
People.get(req.params.id).run().then((person) => {
res.json(person)
}).error((err) => {
res.json({ message: err })
})
}
// 削除
exports.delete = function (req, res) {
People.get(req.params.id).run().then((person) => {
person.delete().then((result) => {
res.json(result)
}).error((err) => {
res.json({ message: err })
})
}).error((err) => {
res.json({ message: err })
})
}
// 更新
exports.update = function (req, res) {
People.get(req.params.id).run().then((person) => {
if(req.body.firstName) {
person.firstName = req.body.firstName
}
if(req.body.lastName) {
person.lastName = req.body.lastName
}
if(req.body.coolnessFactor) {
person.coolnessFactor = parseInt(req.body.coolnessFactor)
}
person.data = r.now()
person.save().then((result) => {
res.json(result)
}).error((err) => {
res.json({ message: err})
})
})
}
詳しくはReQL(RethinkDBのクエリ)のAPIをご覧ください。
エントリーポイント作成
エントリーポイントとなるファイルを作成します。コンソールから呼ばれて実行されるファイルですね。
// ./server.js
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
app.use(express.static(__dirname + '/public'))
app.use(bodyParser.json())
// リアルタイムロギング付与
const People = require('./schema')
const realtimeLogging = require('./realtime')
realtimeLogging(People)
// API利用
const api = require('./api')
app.get('/api/people', api.list)
app.get('/api/people/:id', api.get)
app.delete('/api/people/:id', api.delete)
app.put('/api/people/:id', api.update)
app.post('/api/people', api.add)
app.listen(3000)
起動
スクリプトを叩いて、WebAPIを立ち上げましょう。
$ npm start
あるいは、
$ node server.js
これで、http://localhost:3000/api/people なんて叩くと一覧が取得できます。
データ操作を行うたびに、コンソールにログが出力されます。
余談
GUIツールが欲しい方は、ReQLProがオススメです。