はじめに
前回、単純なルーティング定義をapp.jsに詰め込んだが、app.jsのコードが肥大化してきているので、 express.Router
を使って、ルーティング定義を分割してみる。
express.Routerを使うメリットは以下がありそう。
- コードの整理
ルーティング定義をモジュールに分割できるので、コードを整理できる。 - ミドルウェアの適用
特定のルートに対して、任意の処理を挟み込むことが可能。 - ルートプレフィックス
ルートプレフィックス(URLの先頭部分)を指定できる。 - 可読性
特定の機能やリソースに関連するルートをまとめることで可読性があがる。
express.Router
Routerモジュールの作成
まずルートモジュールをまとめるrouters
フォルダをプロジェクト直下に作成する。
次にusersコレクション用のルートをまとめるためのusersRoutes.js
を作成する。
usersRoutes.js
にルータオブジェクト作成、ルート定義とミドルウェアの設定を行う。
ルータオブジェクト作成
const express = require("express");
const router = express.Router();
const mongoose = require("mongoose");
モデル定義
const Schema = mongoose.Schema;
const userSchema = new Schema(
{
name: String,
age: Number,
},
{ timestamps: true }
);
ミドルウェア設定
router.use((req, res, next) => {
console.log("Time: ", Date.now());
next();
});
ルート定義
// READ
// 全件取得
router.get("/users", async (req, res) => {
try {
const users = await User.find();
res.json(users);
} catch (error) {
res.status(500).json({ error: "ユーザの取得に失敗しました。" });
}
});
// IDでユーザを絞りこみ
router.get("/users/:userId", async (req, res) => {
try {
const userId = req.params.userId;
const user = await User.findById(userId);
res.json(user);
} catch (error) {
res.status(500).json({ error: "ユーザの取得に失敗しました。" });
}
});
// CREATE
router.post("/users", async (req, res) => {
try {
const addUser = req.body;
const newUser = new User(addUser);
await newUser.save();
res.json({ message: "ユーザが登録されました。", user: newUser });
} catch (error) {
res.status(500).json({ error: "ユーザの登録に失敗しました。" });
}
});
// UPDATE
router.patch("/users/:userId", async (req, res) => {
try {
const userId = req.params.userId;
const updateFields = req.body;
// ユーザを更新
const updatedUser = await User.findByIdAndUpdate(
userId,
{ $set: updateFields },
{ new: true }
);
if (!updatedUser) {
return res.status(404).json({ message: "ユーザが見つかりません。" });
}
res.json({ message: "ユーザが更新されました。", user: updatedUser });
} catch (error) {
res.status(500).json({ error: "ユーザの更新に失敗しました。" });
}
});
// DELETE
router.delete("/users/:userId", async (req, res) => {
try {
const userId = req.params.userId;
const deletedUser = await User.findByIdAndDelete(userId);
if (!deletedUser) {
return res.status(404).json({ message: "ユーザが見つかりません。" });
}
res.json({ message: "ユーザが削除されました。", user: deletedUser });
} catch (error) {
res.status(500).json({ error: "ユーザの削除に失敗しました。" });
}
});
モジュールエクスポート
module.exports = router;
ルータモジュールをアプリケーションにロード
app.js
でルータモジュールをロードする。
const userRoutes = require("./routes/usersRoutes");
app.use(userRoutes);
ルートプレフィックスに /api
をつければ、http://localhost:3000/api/users にエンドポイントが作成される。
const userRoutes = require("./routes/usersRoutes");
app.use("/api", userRoutes);
ソースコード
今回作ったプロジェクトは次のGithubで管理
GitHub - ashitaka1963/express_connect_mongodb_sample at f9e13f181e94cdeed9658da27be8fe4a99e42bc8
おわりに
無事にexpress.Routerを使いコード分割を行うことができた。
いまは、MongoDBのユーザコレクションのリソースに対するモジュール分割だけだが、リソースが増えればより効果が出てきそう。
ただ、まだ分割したモジュール内にMongoDB関連のコードが丸っと入っているので、次はこのあたりを整理していく。
参考
Express でのルーティング