TypeScript

【TypeScript】Node.js + MongoDBでAPI開発

TypeScriptの勉強のため、Node.jsをTypeScriptで書いてMongoDBを使い簡単なAPIを作成してみます。

MongoDBの準備

MongoDBの無料プランを利用します。

細かい設定手順は割愛します。

作成したデータベースから Connect > Connect your application から接続文字列を取得します。

この接続文字列は環境変数として使いたいため、.envファイルを作成し中身に記述します。

MONGO_URI="接続文字列"

Node.js / TypeScript の環境設定

node / typescript 環境を準備

npm init
tsc --init

tsconfig.jsonに追記(srcとdistの設定)

"rootDir": "./src",
"outDir": "./dist"

今回必要なパッケージをインストール

※dotenvは接続文字列格納用、mongooseはmongoDBとの接続ライブラリ

npm i @types/express
npm i dotenv
npm i mongoose

最終的なフォルダ構成は下記の通り

必要なフォルダを作成

mkdir controller
mkdir db
mkdir models
mkdir routes

コーディング

今回は下記のようなuserスキーマを定義し、DBに保存するようにします。

    {
        id: { type: Number, required: true },
        name: { type: String, required: true },
        note: String
    }

db/connect.ts

MongoDBとの接続を記述します(dbフォルダ内に配置)

よく分かりませんが、mongoose.set(“strictQuery”, false); を記述しないとエラーになってしまいます

import * as mongoose from "mongoose";

// 末尾に!を付けてstringであることを保証
export const connectDB = () =>{
    const URI = process.env.MONGO_URI!;
    console.log(URI)
    mongoose.set("strictQuery", false);
    return mongoose
        .connect(URI)
        .then(() => console.log("connect to mongoDB"))
        .catch((err:Error) => console.log(err));
};

model/user.ts

インターフェース・スキーマを定義し、モデルをエクスポートします。

https://mongoosejs.com/docs/typescript.html

// import {Schema, model, connect} from "mongoose";
import * as mongoose from "mongoose";

// インターフェースの定義
interface IUser {
    id: number;
    name: string;
    note: string;
};
// スキーマの作成
const userSchema = new mongoose.Schema<IUser>(
    {
        id: { type: Number, required: true },
        name: { type: String, required: true },
        note: String,
    }
);

// モデルの作成、エクスポート
export = mongoose.model<IUser>("User", userSchema);

controller/user.ts

GET/POST/UPDATE/DELETE メソッド毎の処理を記述します。

https://mongoosejs.com/docs/guide.html

import { RequestHandler } from "express";
import UserModel from "../models/user";

export class User {
    getAllUsers: RequestHandler = async (req, res) => {
        try {
            const allUsers = await UserModel.find({});
            res.status(200).json(allUsers);
        }
        catch (err) {
            res.status(500).json(err);
        }
    };

    createUser: RequestHandler = async (req, res) => {
        try {
            const user = await UserModel.create(req.body);
            res.status(200).json(user);
        }
        catch (err) {
            res.status(500).json(err);
        }
    };

    getUser: RequestHandler = async (req, res) => {
        try {
            const user = await UserModel.findOne({ id: req.params.id });
            if (user === null) {
                res.status(500).json(`${req.params.id} is not exist`);
            }
            res.status(200).json(user);
        }
        catch (err) {
            res.status(500).json(err);
        }
    };

    updateUser: RequestHandler = async (req, res) => {
        try {
            const user = await UserModel.findOneAndUpdate({ id: req.params.id }, req.body, { new: true });
            if (user === null) {
                res.status(500).json(`${req.params.id} is not exist`);
            }
            res.status(200).json(user);
        }
        catch (err) {
            res.status(500).json(err);
        }
    };

    deleteUser: RequestHandler = async (req, res) => {
        try {
            const user = await UserModel.findOneAndDelete({ id: req.params.id });
            if (user === null) {
                res.status(500).json(`${req.params.id} is not exist`);
            }
            res.status(200).json(user);
        }
        catch (err) {
            res.status(500).json(err);
        }
    };
}

routes/user.ts

import express from "express";
import {User} from "../controller/user";
const router = express.Router();

// import {
//     getAllUsers,
//     createUser,
//     getUser,
//     updateUser,
//     deleteUser,
// }  from "../controller/user";

const user = new User();
router.get("/", user.getAllUsers);
router.post("/", user.createUser);
router.get("/:id", user.getUser);
router.patch("/:id", user.updateUser);
router.delete("/:id", user.deleteUser);

export = router;

app.ts

import express, { NextFunction } from "express";
import userRoute from "./routes/user";
import {connectDB} from "./db/connect";
const app = express();
const PORT = 3000;
import * as dotenv from 'dotenv'
dotenv.config();

app.use(express.json());
// app.use(express.static("./public"));

// ルーティング
app.use("/api/user", userRoute);

app.use((err:Error, req:express.Request, res:express.Response, next:NextFunction) => {
    res.status(500).json({message:err.message});
});

const start = async () =>{
    try{
        // MongoDBに接続
        await connectDB();
        app.listen(PORT, () => console.log("server listend"));
    }
    catch(err){
        console.log(err);
    }
};

start();

動作確認

メモ:開発時は tsc -w でウォッチモード

コンパイル済みのdist/app.jsを実行します。

node ./dist/app.js

PostmanでPOSTしてみます

MongDBから確認してみると、データが保存されていることが確認できました!!

エンジニアの転職ならこれ!

【第二新卒向け】マイナビジョブ20's

マイナビジョブ20'sは、20代・第二新卒・既卒向けの転職エージェントです。

▼こんな方におすすめ
・はじめて転職しようと思っている
・転職できるだけのスキルが自分にあるか不安
・手厚いサポートを受けたい

【経験者向け】レバテックキャリア

ITエンジニア専門の転職エージェントです。

元エンジニアなど高い専門性を持つアドバイザーが理想の求人を提案してくれます。

▼こんな方におすすめ
・20代後半~40代前半
・年収を上げたい
・スキルアップしたい
・手厚いサポートを受けたい

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です