前回の記事「DockerとExpress.jsを用いたアプリをElastic Beanstalkにデプロイする手順」では、Express.jsを使用してシンプルなWebアプリケーションを開発し、それをDockerでコンテナ化する手順を解説した。
今回は、ExpressアプリとMongoDBを接続し、データの登録から取得までを行う手順をまとめる。尚、当該手順はローカル環境での検証を前提としたものである。
環境
パッケージ
"express": "^4.19.2"
"mongoose": "^8.3.2"
Dockerバージョン: 4.26.1
Docker
の設定
docker-compose.ymlの作成
Docker Compose を使用して、Express と MongoDB のコンテナを同時に起動できるようにする。
# docker-compose記法のバージョン
version: "3.8"
# 起動するコンテナの種類を定義
services:
# Express.jsアプリケーションレイヤーの設定
app-name:
build: .
ports:
- "3000:3000"
environment:
- MONGO_URI=mongodb://mongo:27017/xxxxxxDB
depends_on:
- mongo
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
# mongoDBのコンテナ設定
mongo:
image: mongo
ports:
- "27017:27017"
volumes:
- mongodata:/data/db
volumes:
mongodata:
・サービス名(app-name)の箇所は、プロジェクト名がわかるように任意の名称を設定
・環境変数: MongoDBの接続URIを MONGO_URI 環境変数として設定。これは dist/index.js 内で使用されることを想定。
Express アプリケーションの設定
必要なパッケージのインストール
まず、mongoose
とTypeScriptの型定義ファイルをインストールする。
$ npm i mongoose
$ npm i @types/mongoose --save-dev
TypeScript で MongoDB 接続モジュールを設定
src/db.tsを作成し、以下の実装を行う。
import mongoose from "mongoose";
const mongoURI: string =
process.env.MONGO_URI || "mongodb://localhost:27017/xxxxxxDB";
// データベースへの接続
export const connectDB = async (): Promise<void> => {
try {
await mongoose.connect(mongoURI);
console.log("MongoDB connected successfully");
} catch (error) {
console.error("MongoDB connection error:", error);
// 失敗した場合はアプリケーションを終了
process.exit(1);
}
};
// データベースとの接続解除
export const disconnectDB = async () => {
try {
await mongoose.disconnect();
} catch (error) {
console.error("MongoDB disconnect error:", error);
// 失敗した場合はアプリケーションを終了
process.exit(1);
}
};
アプリケーションでMongoDB 接続モジュールを使用する。
Expressアプリケーションのメインファイル(src/index.ts)で、この接続モジュールをインポートし、アプリケーション起動時にデータベースに接続する。
import express, { Application, Request, Response } from "express";
import { connectDB } from "./db"; // 接続モジュールをインポート
const app: Application = express();
app.use(express.json());
const port = process.env.PORT || 3000;
// DB接続
connectDB();
app.get("/", (req: Request, res: Response) => {
res.send("Hello Docker!");
});
app.listen(port, () => {
console.log(`App listening on port ${port}`);
});
接続確認
`npm run build` を実行し、以下のコマンドでDockerコンテナを起動する。
$ docker-compose up --build
「MongoDB connected successfully」「App listening on port 3000」のログが出力できれば接続に成功している。
ダミーデータの登録
DBとの接続に成功したので、実際にデータを登録してみる。
今回は「職種」データを表現するJobTypeモデルを作成し、/api/master/job-types
にアクセスした際に、登録した職種の一覧が表示されるようにする。
MongoDB スキーマの設定
Mongooseを使用して、JobType
スキーマを定義する。src/models/JobType.ts
を作成する。
import mongoose from "mongoose";
export interface IjobType extends Document {
name: string;
memo?: string;
}
const jobTypeSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
memo: {
type: String,
},
},
{
timestamps: true,
}
);
const JobType = mongoose.model<IjobType>("JobType", jobTypeSchema);
export default JobType;
ダミーデータの挿入
src/test/models/insertData.tsを作成し、以下のコードを記述。
このファイルはnodeコマンドで個別に適用する。
import JobType from "../../models/JobType";
import { connectDB, disconnectDB } from "../../db";
// DB接続
connectDB();
async function insertDummyJobTypes() {
const jobTypes = [
{ name: "Software Developer", memo: "Develops applications." },
{ name: "Data Scientist", memo: "Analyzes complex data." },
{ name: "Product Manager", memo: "Manages product lifecycle." },
];
try {
// 既存のデータをクリア
await JobType.deleteMany({});
// insert
await JobType.insertMany(jobTypes);
console.log("Dummy job types data inserted!");
} catch (error) {
console.error("Error inserting data", error);
} finally {
disconnectDB();
}
}
insertDummyJobTypes();
nodeを実行して、データを登録する。
node src/test/models/insertData.ts
API エンドポイントの作成
src/routes/jobTypes.ts
を作成し、JobType データの取得用のルーティングを設定する。
import express from "express";
import JobType from "../models/JobType";
const router = express.Router();
router.get("/master/job-types", async (req, res) => {
try {
// 一覧を取得
const jobTypes = await JobType.find();
res.json(jobTypes);
} catch (error) {
res.status(500).json({ message: "error fetch jobTypes" });
}
});
export default router;
Expressアプリにルーターを組み込む
Expressアプリケーションのメインファイル(src/index.ts)で、ルーターの設定を行う。
import express, { Application, Request, Response } from "express";
import { connectDB } from "./db";
// ルーターをインポート
import jobTypeRouter from "./routes/jobTypes";
const app: Application = express();
const port = process.env.PORT || 3000;
// DB接続
connectDB();
app.use(express.json());
// ルーターを実行
app.use("/api", jobTypeRouter);
app.get("/", (req: Request, res: Response) => {
res.send("Hello Docker!");
});
app.listen(port, () => {
console.log(`App listening on port ${port}`);
});
以下のコマンドでdockerコンテナを起動する。
$ docker-compose up --build
http://localhost:3000/api/master/job-types
にアクセスすると、登録したデータが表示される。
[
{"_id":"662384c04d417182dcb2f75f","name":"Software Developer","memo":"Develops applications.","__v":0,"createdAt":"2024-04-20T09:02:56.023Z","updatedAt":"2024-04-20T09:02:56.023Z"},
{"_id":"662384c04d417182dcb2f760","name":"Data Scientist","memo":"Analyzes complex data.","__v":0,"createdAt":"2024-04-20T09:02:56.024Z","updatedAt":"2024-04-20T09:02:56.024Z"},
{"_id":"662384c04d417182dcb2f761","name":"Product Manager","memo":"Manages product lifecycle.","__v":0,"createdAt":"2024-04-20T09:02:56.024Z","updatedAt":"2024-04-20T09:02:56.024Z"}
]
コメント