mongoDB, mongooseを使ってCRUDを実装する


CRUDとは

CRUD(クラッド)とは、ほとんど全てのコンピュータソフトウェアが持つ永続性[1]の4つの基本機能のイニシャルを並べた用語。その4つとは、Create(生成)、Read(読み取り)、Update(更新)、Delete(削除)である。

(Wikipediaより)

・CRUDそれぞれに対応するHTTPメソッド

・Create:Postメソッド
・Read:Getメソッド
・Update:Patchメソッド
・Delete:Deleteメソッド

※CRUD処理の為にHTTPメソッドを実装した後は、ちゃんと動くか、Postmanを用いてテストすると良い。
<参考>『Postmanを使ってHTTPに送ったデータを確認する』(https://qiita.com/Molly95554907/items/e367e83129ea1173c317)

CRUDの実装

const express = require('express')
require('./db/mongoose')            //別ファイル(mongooseの読み込み)
const User = require('./models/user')  //別ファイル(mongooseによるuserの定義の読み込み)

const app = express()
//process.env.PORTはherokuで動かす時のポート
const port = process.env.PORT || 3000

//HTTPへ送ったデータを情報の読み取れるようにする
app.use(express.json())

Create

<公式ドキュメント>
・データをデータベースに送る

app.post('/users', (req, res) => {
    const user = new User(req.body)  //リクエストで送ったデータをUserインスタンスに入力

    user.save().then(() => {     //新しく作成したUserインスタンスをDBに保存
        res.status(201).send(user)  //保存成功したら、HTTPステータス201と、保存したデータを返す
    }).catch((e) => {         //保存失敗したら、HTTPステータス400とエラーメッセージを返す
        res.status(400).send(e)
    })
})

<非同期処理(Promise)を用いた実装>


app.post('/users', async (req, res) => {  //asyncで処理した関数はPromiseを返す
    const user = new User(req.body)     //リクエストで送ったデータをUserインスタンスに入力

    try {              //保存成功したら、HTTPステータス201と、保存したデータを返す
        await user.save()
        res.status(201).send(user)
    } catch (e) {
        res.status(400).send(e)   //保存失敗したら、HTTPステータス400とエラーメッセージを返す
    }
})

Read

<公式ドキュメント>
・データをデータベースからとってくる

app.get('/users', (req, res) => {
    User.find({}).then((users) => {   //find({})で全てのデータを取得
        res.send(users)          //取得した全てのデータを返す
    }).catch((e) => {
        res.status(500).send()      //取得失敗したら、HTTPステータス500を返す
    })
})

<非同期処理(Promise)を用いた実装>


app.get('/users', async (req, res) => {
    try {
        const users = await User.find({})  //find({})で全てのデータを取得
        res.send(users)             //取得した全てのデータを返す
    } catch (e) {
        res.status(500).send()         //取得失敗したら、HTTPステータス500を返す
    }
})

Updaet

・データの更新
<公式ドキュメント>
「API > Model」の項目から探す。
・findById
https://mongoosejs.com/docs/api/model.html#model_Model.findById
・findByIdAndUpdate
https://mongoosejs.com/docs/api/model.html#model_Model.findByIdAndUpdate


app.get('/users/:id', (req, res) => {
    const _id = req.params.id  //「:id」に打ち込んだ値を取得

    User.findById(_id).then((user) => {  //「:id」に打ち込んだIDと同じドキュメントを探す
        if (!user) {
            return res.status(404).send() //「:id」に打ち込んだIDと同じドキュメントがなければ、HTTPステータス404を返す
        }

        res.send(user)  //「:id」に打ち込んだIDと同じドキュメントが見つかればそれを返す
    }).catch((e) => {
        res.status(500).send()  //取得失敗したら、HTTPステータス500を返す
    })
})

<非同期処理(Promise)を用いた実装>


app.patch('/users/:id', async (req, res) => {
    const updates = Object.keys(req.body)  //リクエストで送った更新データを取得
    const allowedUpdates = ['name', 'email', 'password', 'age']  //updateできる項目を限定する
    const isValidOperation = updates.every((update) => allowedUpdates.includes(update))  //リクエストで送った更新データがupdateできる項目に当てはまっているか

    if (!isValidOperation) {
        return res.status(400).send({ error: 'Invalid updates!' }) //当てはまっていなければ、HTTPステータス404とエラーメッセージを返す
    }

    try {
        const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true })

        if (!user) {  //「:id」に打ち込んだIDと同じドキュメントを探し、なければHTTPステータス404を返す
            return res.status(404).send()
        }

        res.send(user)   //「:id」に打ち込んだIDと同じドキュメントが見つかればそれアップデートし返す
    } catch (e) {
        res.status(500).send(e)  //取得失敗したら、HTTPステータス500を返す
    }
})

Delete

・データの削除
<公式ドキュメント>
findByIdAndDelete
https://mongoosejs.com/docs/api/model.html#model_Model.findOneAndDelete

app.delete('/users/:id', async (req, res) => {
    try {
        const user = await User.findByIdAndDelete(req.params.id)  //「:id」に打ち込んだIDと同じドキュメントを探し削除

        if (!user) {
            return res.status(404).send()  //「:id」に打ち込んだIDと同じドキュメントがなければHTTPステータス404を返す
        }

        res.send(user)   //「:id」に打ち込んだIDと同じドキュメントが見つかればそれを削除し返す
    } catch (e) {
        res.status(500).send()  //取得失敗したら、HTTPステータス500を返す
    }
})