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
//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 を作成してみました。
今回のものは、リクエストの中身のチェックといったバリデーションが無いです。
次回は、今回の作成物にバリデーションを追加してみようと思います。

ではでは