関連付けされたモデルのREST APIをSequelizeとExpressで作る。

先日から間が開きましたが、先日Sequelizeのモデル関連付けをやってみました。
今回はこのモデルを利用して、REST_API を作成します。

では、本編。

目次

実行環境

  • Windows10 Pro
  • MariaDB 10.3

対象のモデル

今回のモデル作成は、Sequelize でモデルの関連付けを作るで作成したものを使います。
User が複数の Test を持つ 1 対多の関係になっています。

実装

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

./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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//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, { include: [models.Test] }).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();
}
});
};

//以下Testモデルへの問い合わせ。
const indexTest = async (req, res) => {
res.type("json");
models.Test.findAll({ where: { userId: req.params.id } }).then((tests) => {
res.status(200).send(JSON.stringify(tests));
});
};

const createTest = async (req, res) => {
res.type("json");
models.User.findOne({
where: { id: req.params.id },
include: [models.Test],
}).then((user) => {
user.createTest(req.body).then((test) => {
res.status(201).send(JSON.stringify(test));
});
});
};
const showTest = async (req, res) => {
res.type("json");
models.Test.findOne({
where: { userid: req.params.id, id: req.params.tid },
}).then((test) => {
res.status(201).send(JSON.stringify(test));
});
};
const updateTest = async (req, res) => {
res.type("json");
models.Test.update(req.body, {
where: { userid: req.params.id, id: req.params.tid },
})
.then((result) => {
if (result >= 1) {
res.status(200).end();
} else {
res.status(400).end();
}
})
.catch((Err) => {
res.status(400).end(Err.message);
});
};

const destroyTest = async (req, res) => {
res.type("json");
models.Test.destroy({
where: { userid: req.params.id, id: req.params.tid },
}).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);

//
app.get("/users/:id/tests", indexTest);
app.post("/users/:id/tests", createTest);
app.get("/users/:id/tests/:tid", showTest);
app.patch("/users/:id/tests/:tid", updateTest);
app.delete("/users/:id/tests/:tid", destroyTest);

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

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

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

これで関連付けしたモデルへの REST API サーバができました。


今回は、先日作成した関連付けモデルでの REST API サーバを作成しました。
もう少しやれることがあるので、もうしばらくSequelizeとは付き合ってみようと思っています。
現在考えているところは、INNER JOIN です。
後は、Sequelize を使ってアプリケーションまで持ってゆきたいのですが、ネタが無いなぁ。

ではでは。