TL;DR
Knex.jsを使用したMigrationとSeedの作成の続きです。
Objection.jsを使用してAPIを実装してみたいと思います。
実装後はこちら
Objection.jsとは
前回少し触ったKnex.jsを内包したNode.jsのORMです。
クエリはKnexを使用するため、DBサポートはKnexと同様にSQLite3、PostgreSQL、MySQLをサポートしています。
Objectionを使うことによりObjectionでモデルを定義すると、そのモデルクラスを元に、DB操作を行う事ができるようになります。
また、そのモデル自体にJsonSchemaによるバリデーションを定義できます。
Modelファイルの作成
model/User.js
を作成します。
公式ではjsonSchemaを記載していたりしますが、Joi
を元に joi-to-json-schema
を使ってjsonSchemaを作りました。
'use strict'
const Model = require('objection').Model
const Joi = require('joi')
const convert = require('joi-to-json-schema')
class User extends Model {
// table name
static get tableName() {
return 'user'
}
// validate
static get jsonSchema() {
const joiSchema = Joi.object({
name: Joi.string().min(4).max(50).required(),
email: Joi.string().email().max(100).required(),
password: Joi.string().min(6).max(200).required(),
})
return convert(joiSchema)
}
}
module.exports = User
Routeの実装
前回でも行っているuserモデルのAPIを作ります。
ObjectionのModelを作っていると Model.query()
で Modelで定義しているテーブルの一覧、の結果を簡単に得ることができます。
const User = require('../model/User')
const md5 = require('md5')
module.exports = [
{
method: 'GET',
path: '/user',
handler: async (request, h) => {
try {
const user = await User.query()
return user.map((elem) => {
delete elem.password
return elem
})
} catch (err) {
return h.response({ ...err }).code(err.statusCode || 500)
}
}
},
{
method: 'POST',
path: '/user',
handler: async (request, h) => {
const data = request.payload
data.password = md5(data.password)
try {
const user = await User.query().insert(data)
return { message: 'created' }
} catch (err) {
return h.response({ ...err }).code(err.statusCode || 500)
}
}
},
{
method: 'GET',
path: '/user/{id}',
handler: async (request, h) => {
try {
const user = await User.query().where({ id: request.params.id })
console.log(user);
if (!user[0]) return h.response({ statusCode: 404 }).code(404)
delete user.password
return user
} catch (err) {
return h.response({ ...err }).code(err.statusCode || 500)
}
}
},
{
method: 'PUT',
path: '/user/{id}',
handler: async (request, h) => {
try {
const user = await User.query().patchAndFetchById(request.params.id, request.payload)
if (!user) return h.response({ statusCode: 404 }).code(404)
return { message: 'updated' }
} catch (err) {
return h.response({ ...err }).code(err.statusCode || 500)
}
}
},
{
method: 'DELETE',
path: '/user/{id}',
handler: async (request, h) => {
try {
const user = await User.query().deleteById(request.params.id)
console.log(user);
if (!user) return h.response({ statusCode: 404 }).code(404)
return { message: 'deleted' }
} catch (err) {
return h.response({ ...err }).code(err.statusCode || 500)
}
}
},
]
以上で、 /user/
と /user/{id}
のAPIが動作するようになるかと思います。