🎃

express × Mongo DBでCRUDするweb APIを作る(その1 Mongo DB編)

2021/12/26に公開

はじめに

本稿では自作webAPIの作成から実行、活用するところまでを3編に分けて、紹介します。

その1概要(MongoDBでCRUD) ☆今回

MongoDBをインストールする〜MongoDBでCRUDするところまでを説明します。

その2概要(webAPIの作成と実行)

expressとMongoDBでwebAPIの作成〜Postmanで自作webAPIを実行するところまでを紹介します。

その3概要(webAPIの活用)

実際にNuxt.jsを使用して画面から自作APIを呼び出して、Mongo DBに反映させる&画面に表示をするところまでを紹介します。

対象

expressを使ってwebアプリケーションの基礎であるCRUDできるAPIを作ってみたいという方
APIとはどんな流れで使用されているのか知りたい方

今回の記事での事前準備

node.js
homebrew

※mac環境を想定しています。
以下、私の環境

// node.jsのバージョン
$ node -v
v14.17.6

// homebrewのバージョン
$ brew -v
Homebrew 3.3.4
Homebrew/homebrew-core (git revision 4567f25b438; last commit 2021-11-20)
Homebrew/homebrew-cask (git revision fbb42995b4; last commit 2021-11-20)

もし何も出なかったりしたらインストールできていないので、以下を参考にインストールしてください。
MacにNode.jsをインストール

Mongo DBのインストール

nodeとhomebrewのインストール後、Mongo DBをインストールします。

//MongoDB公式ソフトウェアのTapをインストール
$ brew tap mongodb/brew

// Mongo DB(ローカル環境)をインストール
$ brew install mongodb-community

// Mongo DBのバージョン確認(私の場合は以下のバージョン)
$ mongod --version
db version v5.0.3
Build Info: {
    "version": "5.0.3",
    "gitVersion": "657fea5a61a74d7a79df7aff8e4bcf0bc742b748",
    "modules": [],
    "allocator": "system",
    "environment": {
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}

mongodb-communityインストール後、MongoDBの設定ファイルが/usr/local/etc/mongod.confに作成されます。

mongod.confにはローカルのMongo DBの接続先やログの出力先が記載されています。

Mongo DBの起動/停止/確認方法

以下と同じ流れでMongo DBの起動と停止を確認します。

// Mongo DBの状態確認(以下は私の状況)
$ brew services list
Name              Status  User File
dbus              stopped      
mongodb-community stopped      
mysql             stopped      
postgresql        stopped
 →mongodb-community stoppedが記載されていれば大丈夫です。

// Mongo DB起動
$ brew services start mongodb-community
==> Successfully started `mongodb-community`......

// Mongo DBの状態確認(起動確認)
$ brew services list
Name              Status  User      File
dbus              stopped           
mongodb-community started ここはUser名 ここはfile名
mysql             stopped           
postgresql        stopped 
 →mongodb-community startedが記載されていれば大丈夫です。

// Mongo DB停止
$ brew services stop mongodb-community
==> Successfully stopped `mongodb-community` ......

// Mongo DBの状態確認(停止確認)
$ brew services list
Name              Status  User File
dbus              stopped      
mongodb-community stopped      
mysql             stopped      
postgresql        stopped
 →mongodb-community stoppedが記載されていれば大丈夫です。

Mongo DBの起動/停止/確認ができたら、使用できるように、起動しておきます。

// Mongo DB起動
$ brew services start mongodb-community

// Mongo DBの状態確認(起動確認)
$ brew services list
Name              Status  User      File
dbus              stopped           
mongodb-community started ここはUser名 ここはfile名
mysql             stopped           
postgresql        stopped 

Mongo DBへの接続

Mongo DB起動のあと、以下のコマンドでmongo DBへ接続をします。

// Mongo DBへの接続
$ mongo
MongoDB shell version v5.0.3
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
....

>

最後に ">" と出てこれば、入力待ち状態なのでOKです。
これでmongo DBを使用できるようになりました。

Mongo DB(NoSQL) と RDB(MySQLなど)の違い

Mongo DBはNoSQLのためRDB(Relational DataBase)と少し構造が異なります。

RDBでの呼称 MongoDBでの呼称
データベース データベース
テーブル コレクション
カラム(column) フィールド(field)
レコード(row) ドキュメント(document)
フィールド ドキュメントのフィールド

Mongo DBでの操作

Mongo DBでは、他のRDBと同様に、データベースとコレクション(テーブル)、ドキュメント、カラムがあり、それぞれCRUDがあります。今回はそれぞれをCRUDを紹介していきます。

- データベースのCRUD(作成/読み込み/更新/削除)

Mongo DBは入力されたデータベース名が存在しない場合は、自動でデータベースを作成してくれて、かつ、そのDBをすぐに使えるように、switchしてくれます。

ただし、一つもコレクションがない状態でshow dbsしても、一覧に出てこないので、注意してください。

// データベースの作成(create)
> use company
switched to db company

// データベースの読み込み(read)
// 一度もDBを作ったことない場合でも、以下3つのDBは作成済みとなっています。
> show dbs
admin    0.000GB
config   0.000GB
local    0.000GB
※ 上記でcompanyデータベースを作成しましたが、コレクションが1つもはいっていないため、表示されません。

// データベース名の更新(update)
// Mongo DBのバージョン4.2以前の場合
// 新しい名前をつけて複製して、古いデータベースを削除します(直接名前の更新することはできないようです)
> db.copyDatabase('company', 'new_company');
> use old_name
> db.dropDatabase()

Mongo DBのバージョン4.2以降だとcopyDatabaseコマンドが使えなくなったため、上の方法ではできなくなっています。4.2以降ですと、mongodumpコマンドとmongorestoreコマンドを使ってデータベースの命名を変更します。詳しくは以下を参照
https://docs.mongodb.com/database-tools/mongodump/#std-label-mongodump-example-copy-clone-database
https://nodejs.keicode.com/mongodb/backup-and-restore.php

- コレクションのCRUD(作成/読み込み/更新/削除)

コレクションの作成(create)

// コレクションの作成(create)
> db.createCollection("member")
{ "ok" : 1 }

コレクションの読み込み(read)

// コレクションの読み込み(read)
> show collections
member
※現在company データベース内になるコレクションの一覧が表示される。

コレクション名の更新(update)

// コレクション名の更新(update)
> db.member.renameCollection("new_member")
{ "ok" : 1 }

// コレクションの確認
> show collections
new_member
※memberコレクションからnew_memberコレクションが作成されたことが確認できる。

コレクションの削除(delete)

// コレクションの削除
> db.new_member.drop()
true

// コレクションの確認
> show collections
※new_memberコレクションが削除されたことが確認できる。

以上が、コレクションでのCRUD操作になります。
コレクションのCRUDが一通り確認できたので、今後の操作のために、memberコレクションを作成しておきます。

> db.createCollection("member")
{ "ok" : 1 }

> show collections
member

- ドキュメントのCRUD(作成/読み込み/更新/削除)

Mongo DBではドキュメント作成時に、同時にカラムも作成される仕様になっていますので、事前にカラムを作っておく必要はありません。

ドキュメントの作成(create)

// ドキュメントの作成(create)
>db.member.insert({name: "田中太郎", age: 22, permanent_staff: true})
WriteResult({ "nInserted" : 1 })
>db.member.insert({name: "鈴木次郎", age: 24, permanent_staff: true})
WriteResult({ "nInserted" : 1 })
>db.member.insert({name: "佐藤三郎", age: 35, permanent_staff: false})
WriteResult({ "nInserted" : 1 })

ドキュメントの読み込み(read)

// ドキュメントの読み込み(read)
// 以下は全件検索の例
> db.member.find()
{ "_id" : ObjectId("61c83b5933e8df1f3fd1986e"), "name" : "田中太郎", "age" : 22, "permanent_staff" : true }
{ "_id" : ObjectId("61c83b6133e8df1f3fd1986f"), "name" : "鈴木次郎", "age" : 24, "permanent_staff" : true }
{ "_id" : ObjectId("61c83b6833e8df1f3fd19870"), "name" : "佐藤三郎", "age" : 35, "permanent_staff" : false }

※memberコレクションに入っているデータを全て表示

// 条件を指定した検索の例
> db.member.find({permanent_staff: true})
{ "_id" : ObjectId("61c83b5933e8df1f3fd1986e"), "name" : "田中太郎", "age" : 22, "permanent_staff" : true }
{ "_id" : ObjectId("61c83b6133e8df1f3fd1986f"), "name" : "鈴木次郎", "age" : 24, "permanent_staff" : true }

※permanent_staffカラムの値がtrueのドキュメントのみを表示

上記でお気づきの方もいらっしゃると思いますが、Mongo DBではドキュメントを新規作成すると、"_id"が勝手に付加されてます、これはObjectIdというもので、自動的に一意(ユニーク)な値が割り振られます。

現在のmemberコレクションの状態

name age permanent_staff
"田中太郎" 22 true
"鈴木次郎" 24 true
"佐藤三郎" 35 false

ドキュメントの更新(update)

// ドキュメントの更新(update)
> db.member.update({name: "田中太郎"},{$set: {age: 20}}, {multi: true})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.member.find({name: "田中太郎"})
{ "_id" : ObjectId("61c83b5933e8df1f3fd1986e"), "name" : "田中太郎", "age" : 20, "permanent_staff" : true }
※"田中太郎"のageカラムの値が20になったことを確認

現在のmemberコレクションの状態

name age permanent_staff
"田中太郎" 20 true
"鈴木次郎" 24 true
"佐藤三郎" 35 false

ドキュメントの削除

// ドキュメントの削除
> db.member.remove({name: "田中太郎"})
WriteResult({ "nRemoved" : 1 })

> db.member.find()
{ "_id" : ObjectId("61c83b6133e8df1f3fd1986f"), "name" : "鈴木次郎", "age" : 24, "permanent_staff" : true }
{ "_id" : ObjectId("61c83b6833e8df1f3fd19870"), "name" : "佐藤三郎", "age" : 35, "permanent_staff" : false }

※nameカラムが"田中太郎"のドキュメントがないことを確認

現在のmemberコレクションの状態

name age permanent_staff
"鈴木次郎" 24 true
"佐藤三郎" 35 false

- カラムのCRUD(作成/読み込み/更新/削除)

カラムの新規作成

// カラムの新規作成
>db.member.update(
 {},
 { $set: { "language_type" : "日本語"}},
 false,
 true
)
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })

// language_typeカラムの新規作成を確認
> db.member.find()
{ "_id" : ObjectId("61c83b6133e8df1f3fd1986f"), "name" : "鈴木次郎", "age" : 24, "permanent_staff" : true, "language_type" : "日本語" }
{ "_id" : ObjectId("61c83b6833e8df1f3fd19870"), "name" : "佐藤三郎", "age" : 35, "permanent_staff" : false, "language_type" : "日本語" }

現在のmemberコレクションの状態

name age permanent_staff language_type
"鈴木次郎" 24 true "日本語"
"佐藤三郎" 35 false "日本語"

カラムの更新(Update: 名前変更)

// カラムの更新(Update: 名前変更)
> db.member.updateMany( {}, { $rename: {"language_type":"language" } } )
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

// languageカラムへの命名変更を確認
> db.member.find()
{ "_id" : ObjectId("61c83b6133e8df1f3fd1986f"), "name" : "鈴木次郎", "age" : 24, "permanent_staff" : true, "language" : "日本語" }
{ "_id" : ObjectId("61c83b6833e8df1f3fd19870"), "name" : "佐藤三郎", "age" : 35, "permanent_staff" : false, "language" : "日本語" }

現在のmemberコレクションの状態

name age permanent_staff language
"鈴木次郎" 24 true "日本語"
"佐藤三郎" 35 false "日本語"

カラムの削除(Delete)

// カラムの削除(Delete)
> db.member.update({},{$unset: {language:1}}, {multi: true})
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })

> db.member.find()
{ "_id" : ObjectId("61c83b6133e8df1f3fd1986f"), "name" : "鈴木次郎", "age" : 24, "permanent_staff" : true }
{ "_id" : ObjectId("61c83b6833e8df1f3fd19870"), "name" : "佐藤三郎", "age" : 35, "permanent_staff" : false }

現在のmemberコレクションの状態

name age permanent_staff
"鈴木次郎" 24 true
"佐藤三郎" 35 false

最後に

この記事ではMongoDBをインストールするところから、MongoDBの各CRUDを説明しました。
次回は、このCRUDを使って、express × Mongo DBでCRUDするweb APIを作っていきます。

Discussion