REST APIをバリデーションも踏まえてSequelizeとExpressで作る。

前回、Node.js向けORM Sequelize のバリデーションとエラーハンドリングSequelizeのバリデーションを試したので、
Expressを絡めたRESTAPIの作成で作成したRESTAPIをバリデーションを踏まえて修正してみます。

実装

前回から引き続き、アクセスするモデルは文字列nameと整数ageを持つUserです。
それぞれのバリデーションの内容は以下の通りです。

  • name
    • null禁止
    • 空文字列禁止
    • 文字列長を1~20に拘束
  • age
    • null禁止
    • 空文字禁止
    • 整数に拘束
    • 最小値を12に拘束
    • 最大値を100に拘束

上記に基づいて、設定したUserモデルが以下のuser.jsとなります。

models\user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'use strict';
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
name:{
type:DataTypes.STRING,
allowNull: false,
validate:{
notNull: {msg: 'Please param to "name"'},
notEmpty: {msg: 'Please not enpty param to "name"'},
len:[1,20]
}
},
age:{
type:DataTypes.INTEGER,
allowNull: false,
validate:{
notNull: {msg: 'Please param "age"'},
notEmpty: {msg: 'Please not enpty param to "age"'},
isInt: true,
min:12,
max:100
}
}
}, {});
User.associate = function(models) {
};
return User;
};

こちらを呼び出す、Expressアプリのコードが以下の通りです。

./src/index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//Express関連読み込み
const express = require(`express`)
const bodyparser = require(`body-parser`)

//モデルを読み込み
const models = require('../models');

//アプリケーション作成
const app = express()
app.use(bodyparser.urlencoded({extended:false}))
app.use(bodyparser.json())

//アクション:データベースアクセス、レスポンス定義
const index = async(req,res)=>{
res.type('json')
models.User.findAll().then(users=>{
res.status(200).send(JSON.stringify(users))
});
}

const show = async(req,res)=>{
models.User.findByPk(req.params.id).then(users=>{
res.type('json')
if(users!=null){
res.status(200).send(JSON.stringify(users))
}
else{
res.status(404).end();
}
});
}

const create = async(req,res)=>{
res.type('json')
models.User.create(req.body)
.then((User) => {
res.status(201).send(JSON.stringify(User))
})
.catch((Err)=>{
res.status(400).end(Err.message)
})

}

const update = async(req,res)=>{
res.type('json')
models.User.update(req.body,{where: {id: req.params.id}})
.then((result) => {
if(result>=1){
res.status(200).end()
}
else{
res.status(400).end()
}
})
.catch((Err)=>{
res.status(400).end(Err.message)
})
}

const destroy = async(req,res)=>{
res.type('json')
models.User.destroy({where: {id: req.params.id}})
.then((result)=>{
if(result==1){
res.status(204).end();
}else{
res.status(404).end();
}
})
}

//ルーティング定義
app.get('/users',index)
app.post('/users',create)
app.get('/users/:id',show)
app.patch('/users/:id',update)
app.delete('/users/:id',destroy)

//サーバ起動時使用ポート定義
const port = process.argv[2]==null?3000:process.argv[2]

//サーバ開始
app.listen(port);
console.log(`Start Server at ${port}!!`)

こちらをnode src\index.jsで起動します。
適当なRESTクライアントでアクセスし、動作確認します。
バリデーションによってはじかれることを確認できるはず。
以前バリデーションが無いために機能しなかったcreateとupdateはのエラー処理が機能するようになりました。

一旦ここまで出来れば、シンプルなものは作れそうです。
Railsを挟んで一般的な形を一旦学べたことはNode.jsの学習を進めるうえでも非常に良かったです。
次は、複数モデルの関連付けになるのかなと思う次第です。

ではでは