🌟

MERN stack appを作ってみる

2022/09/28に公開

始めに

今回はMERN stack app(MongoDB, Express, React, and Node)の導入をしてみましたので、その方法をご紹介します。
今回の目標としては、MongoDBとReactプロジェクトを繋ぎ、実際にサーバサイドからクライアントサイドへのデータの受け渡しが出来るまでとします。

今回は元々作成していたReactアプリケーションで使用していたsassの影響で

  • MongoDBはversion 4.4.1
  • node.jsはversion 14.17.6
    を使用しています。

また、フロント画面側はAPI処理を除き、処理や説明を省きます。

もし必要でしたらnvmのインストールをしておくことをお勧めします。
https://github.com/nvm-sh/nvm

nvmとはnode.jsのバージョンを簡単に変更できる便利なコマンドラインツールになります。

今回の目次

  • MongoDBとは

  • MongoDBでデータベースを作成する。

  • 実際のフロント画面(REACT)との接続まで手順

MongoDBとは

MongoDBについてはNoSQLデータベースの1種としてエンジニアの方なら一度は聞いたことのあるDBだと思います。

そもそもNoSQLデータベースとは

一言でいうと、RDB(R elational D ata b ase)以外のデータベースのことを指します。

RDBとは
日本語訳すると相関的なデータベースです。
代表的なものとしてMySQLやOracleなどがあり、データを複数の表(テーブル)として管理し、テーブル毎の関係を定義することにより複雑なデータの関連性を扱えるようにしたデータベース管理方法のことを言います。

なぜNoSQLを使用するのか

近年のIoTやAI技術の発展に伴い、ビッグデータのような膨大なデータを扱うシーンが増えてきたこと、また、ビッグデータに含まれる非構造化(内容に一定の規則性はあるが、表形式にはなっていないデータ)、半構造化データ(内容に規則性のないデータ)をRDBでは扱えない為、NoSQLが広く使用されるようになって来ました。

NoSQLはデータをより高速に処理でき、また、非構造化、半構造化データの処理を行うことが出来ます。

MongoDBのデータ管理

では、MongoDBはどのようにしてデータを管理しているのでしょうか。

MongoDBは Field&Value Pair の構造で、ドキュメント指向のデータベースでJSON、のようなドキュメント形式でデータを管理しています。
このValueにはArrayやその他の形式のドキュメントを保持する事が出来ます。

また、このドキュメントは collections として管理されます。

では、少しMongoDBについて理解したところで、実際にMongoDBのインストール方法を説明していきます。

もしまだMongoDBについて知りたい方がいらっしゃれば公式ページをご参照ください。
https://www.mongodb.com/docs/manual/introduction/

MongoDBのインストール

MongoDBのインストール手順については公式のホームページにしたがってインストールしましょう。
Atlasへサインアップなど初期設定は完了している状態まで完了している前提で進めます。
(今回は割愛させて頂きますが、機会があればこの辺りの手順は別記事としてでも記事にしようと思います。)

MongoDB(Atlas)でデータベース(Cluster)を作成する。

Atlasに接続出来るようになればデータベースを作成してみましょう。

プロジェクトの作成

  1. 「Projects」から「New Project」を押下。
  2. プロジェクト名を入力したら、Nextを押下。
  3. プロジェクトにメンバーを追加

データベースの作成

  1. 画面左側の「DEPLOYMENT」→「Database」を選択します。

  2. 画面中央の「Build a Database」を押下します。

  3. DBの構成について
    お好みで設定していただければいいんですが、今回は無料の構成で作成する為、下記の構成としました。
    Cluster: 「Shared」
    Cloud Provider:「aws」
    Region:「Tokyo」
    Cluster Tier:「M0」
    Additional Settings:「Mongodb.5.0, No Backup」
    Clustername:「sample」※任意の名前を付けてください。

  4. userの追加
    A.Username and Password選択の場合、user名とパスワードを設定し、Built-in Roleで何かしらの権限を設定し、「Create User」を押下しましょう。(こちらは後からでもSECURITY→Database Accessから追加や編集を行えます。)
    B.今回はローカル環境用のClusterを作成するので、「My Local Environment」を選択し、IP Addressを追加(特別な設定がない場合は、「Add My Current Ip Address」を押下でOK)し、「Finish and Close」を押下します。

  5. ここまで完了したらMongoDB Compassにも設定を行いましょう。
    MongoDB Compass を開き、New Connectionを押下。
    URIにAtlasで表示されているURIを貼り付けて「Connect」押下。
    <username>、<password>にはそれぞれ先ほど4.1.で作成したユーザのuser名とパスワードを入力してください。

  6. MongoDB Compassへ接続が完了したら簡単にcollectionとdataを追加しましょう。
    1.「create collection」→collectionに名前を付けて(今回はpeopleとします。)「Create Collection」します。
    2.作成出来たらcollectionの中に入り、「ADD DATA」を押下します。
    今回は「Insert Document」します。

下記のようなデータを登録してみましょう。

{
    "_id": {
        "$oid" : "6239u0we0jd91" 
    },
    "name" : "Brian Leung",
    "age" : 35,
    "sex" : "man"
}

ここまで出来たら次は実際のReactプロジェクトへ接続してみましょう。

実際のフロント画面(REACT)との接続まで手順

ファイルのディレクトリ構造(バックエンド)
─ backend
 ├ node_modules
  ─モジュールが入る
 ├ server
  ├ config
   ├ db.config.js
 ├ db
  ├ conn.js
 ├ models
  ├ people.js
  ├ people.model.js
 ├ routes
  ├ people.js
 ├ config.env
 ├ server.js
 ├ package-lock.json
 ├ package.json

  1. npmモジュールのインストール
    先ずは今回使用するモジュールをインストールしましょう。
    npm install express mongoose cors dotenv --save

ここで出てきたモジュールについて解説

express:RestAPIを作成する。
mongoose:モデルを生成する。
cors:CORSを有効化する為の様々なExpress middlewareを提供する。
dotenv:環境変数を定義する。

今回は使用しませんが、重要なモジュール
body-parser:リクエストのbody部分の解析や、req.bodyobjectを生成する。

  1. /backend/server.jsの作成。
    ファイルを作成したら下記を記載します。
const express = require("express");
const app = express();
const cors = require("cors");
require("dotenv").config({ path: "./config.env"});
const port = process.env.PORT || 5000;
app.use(cors());
app.use(express.json());
app.use(require("./routes/people"));

const dbo = require("./db/conn");

const db = require("./modules/people");

mongoose.connect(db.url, {
  useNewUrlParser : true, useUnifiedTopology : true
}) 
.then(()=>{ 
  console.log(`connected to db`); 
})
.catch(err=>{ 
  console.log(err); 
});

app.listen(port, () => {
    // preform a database connection when server starts
    dbo.connectToService(function(err) {
        if (err) console.error(err);
    });
    console.log(`Server is running on port: ${port}`);
});
  1. config.envの作成
ATLAS_URL=atlasのURIをここにも貼り付け
PORT=5000
  1. /config/db.config.jsの作成
module.exports = {
    url: "mongodb://localhost'27017/${DatabaseName}"//Database名を入れましょう。
}
  1. backend/models/people.jsの作成
const dbConfig = require("../config/db.config.js");

const mongoose = require("mongoose");
mongoose.Promise = global.Promise;

const db = {};
db.mongoose = mongoose;
db.url = dbConfig.url;
db.people = require("./people.model.js")(mongoose);

module.exports = db;
  1. backend/models/people.model.jsの作成
    ここではpeople collectionより取得するデータや型の指定をします。
module.exports = mongoose => {
  const People = mongoose.model(
    "people",
    mongoose.Schema(
      {
        name : String,
        age : Integer,
        sex : String
      },
      { timestamps: true }
    )
  );

  return People;
};
  1. backend/routes/people.jsの作成
    ここがAPI的な役割を持つので、今回はデータ全取得だけですが、peopleのCRUDは全てここに記載する。
const express = require("express");

const recordRoutes = express.Router();

const dbo = require("../db/conn");

const ObjectId = require("mongodb").ObjectId;

recordRoutes.route("/people").get(function (req, res) {
    let db_connect = dbo.getDb(${DatabaseName});//Database名を入れましょう。
    db_connect
        .collection("people")
        .find({})//何かしら条件を入れたい場合はここに記載。
        .toArray(function (err, result) {
            if (err) throw err;
            res.json(result);
        });
});
  1. フロント画面との接続。
    今回はReactでの処理となるので、ReactHooksのuseState, useEffectを使用して実装します。
    今回は折角なので、fetchを使用する方法とXMLRequestを使用する方法との2つをご紹介します。

fetchを使用する方法

import React, { useState, useEffect } from "react";

const SamplePage = () => {
    const [people, setPeople] = useState();
    useState(() => {
        fetch("http://localhost:5000/people")
        .then(response => response.json())
        .then(data => setPeople(data));
        .catch(error => console.log(error))
    },[])

    console.log(people);

    return(
        <>{/* Components would be here*/}</>
    )
}

XMLHTTPRequestを使用する方法

import React, { useState, useEffect } from "react";

const SamplePage = () => {
  const [people, setPeople] = useState();
  useEffect(()=>{ 
    var request = new XMLHttpRequest(); 
    request.onreadystatechange = function() { 
      if (request.readyState === 4 && request.status === 200) { 
        const response = JSON.parse(request.response);
        setPeople(response)
      } 
    }; 
    request.open('GET', 'http://localhost:5000/people', true); 
    request.send(); 
  },[]);

  console.log(people);

  return(
    <>{/* Components would be here*/}</>
  )

これで該当のページを開き、logにデータが出力されていれば完了です。
※補足:一番利用されていることが多そうなのはaxiosを使った方法だと思うのですが、GET Methodにおいてはfetchとほとんど変化がないので、今回は省きました。

まとめ

今回はMERNを使用したスタックアプリケーションをご紹介させて頂きました。
今後ますます使用されることが多くなっていくであろうMongoDB(NoSQL)なので、軽く繋がりなどが分かっていると今後に役立つ事があるかもしれませんね。

今回に関しては実装は個人用のPCで実施したため、実際のスクショ等がなく少し文字ばかりで分かりずらかったらすみません。
MongoDBに関してはまだまだこれから勉強していく分野なので、無駄な処理やもっとこうすれば簡単なのにと思う事があるかもしれません。もし何か有りましたらコメント等でご教示頂ければと思います。
ここまで読んでくださりありがとうございました。

参考

https://www.bezkoder.com/react-node-express-mongodb-mern-stack/#MERN_stack_Architecture

https://www.pluralsight.com/guides/get-json-of-mongo-collection-with-and-xhr-request

Discussion