REST APIをSequelizeとExpressで作る。

先日Node.js向けORM Sequelizeで書いた通り、Sequelizeでmariadbにアクセスしてみました。
本来は、Sequelizeを使ってRESTAPIの仕組みが作りたかったので、今度こそ作ってみます。

参考資料

同じようなことやってる人がたくさんいますね。

実行環境

  • Windows10 Pro
  • MariaDB 10.3

参考にするRailsでのAPIサーバ

以前、作成したproductというモデルに問い合わせするrailsのアプリのルーティングを確認してみます。
Railsアプリが置いてあるディレクトリで,rails routesを実行。
productに関連するルーティングを抽出すると以下のようになっています。

1
2
3
4
5
6
7
  Prefix Verb   URI Pattern                  Controller#Action
products GET /products(.:format) products#index
POST /products(.:format) products#create
product GET /products/:id(.:format) products#show
PATCH /products/:id(.:format) products#update
PUT /products/:id(.:format) products#update
DELETE /products/:id(.:format) products#destroy

以上と同じ要件の問い合わせと同じルーティングとデータベースへの操作を実装することにします。
updateするものはPATCHのみとし、5つのルーティングを作成するものとします。

作成

前回のNode.js向けORM Sequelizeをそのまま利用するものとしてやってみます。

パッケージ追加

必要なExpress関連パッケージを追加します。

1
2
npm install express --save
npm install body-parser --save

ここまでのパッケージの導入状況はpackage.jsonから抜粋すると以下のようになります。

package.json
1
2
3
4
5
6
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"mysql2": "^1.7.0",
"sequelize": "^5.19.6"
},

実装

以下の通り実装しました。

./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
//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)=>{
models.User.findAll().then(users=>{
res.type('json')
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)=>{
models.User.create(req.body)
.then((User) => {
res.type('json')
if(User.dataValues!=null){
res.status(201).send(JSON.stringify(User))
}
else{
res.status(400).end()
}
})
}

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

const destroy = async(req,res)=>{
models.User.destroy({where: {id: req.params.id}})
.then((result)=>{
res.type('json')
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)

//サーバ開始
app.listen(3000);
console.log("Start Server!!")

以上を作成しnode ./src/index.jsで実行。
適当なRESTクライアントでアクセスし、動作確認します。

エラー時のエラーコードは、Railsで作成したAPIでの実験結果を反映して、
400と404で使い分けてみました。
ただし、バリデーションが入っていない故にcreateとupdateはのエラー処理は、現在のところ効果をなしていないですね・・・。


今回は、Railsを参考に、node.jsでRESTAPIを作成してみました。
今回のものは、リクエストの中身のチェックといったバリデーションが無いです。
次回は、今回の作成物にバリデーションを追加してみようと思います。

ではでは