初めに
フロントエンドエンジニアになって7ヶ月が経ちました。最近サーバーにも興味が出てきたのでフロントと相性の良さそうな Node.js と、そのフレームワークの Express を使ってAPIを作ってみます。あと MongoDBとかいう子が Node/Express のプロジェクトでよく使われるっぽいので一緒に入門してみます。
サーバー初心者なのでその辺はあしからず、、
本記事で取り扱うこと
- Node.js / Express を用いたAPI作成しPostmanで動作確認をする
- MVCモデルっぽく作ってみる
- MongoDBとの接続
扱わないこと
- DB設計とかの踏み込んだ部分
- Typescript との連携
- Vue / React などのフレームワークとの繋ぎ込み
- EJSなどのテンプレートエンジン
バージョン
Node
Express
Mongoose
ディレクトリ構成
node-project
├── controllers
│ └── controller.js
├── models
│ └── model.js
├── routes
│ └── route.js
├── node_modules
├── .env
├── app.js
├── package.json
└── package-lock.json
プロジェクトの作成からサーバーの立ち上げまで
この項目でやること
- プロジェクトの作成
- 必要なパッケージのインストール
- 5000番ポートでのサーバーの立ち上げ
ディレクトリ作成
フォルダを作りましょう
フォルダ名は任意のもので大丈夫です。
mkdir node-project
cd node-project
package.json作成
npm init -y
package.json が自動作成される
ちなみに -y をつけることでデフォルトの設定になりますが、つけないと自分好みにカスタマイズできるらしいです(参考サイト)
必要なパッケージのインストール
今回は下記3つのパッケージをインストールしていきます。
- express
- mongoose
- dotenv
- nodemon
npm i express mongoose dotenv nodemon
mongooseとは
- MongoDBを操作するためのnpmモジュール。
- MongoDB用モデリングツールで、Node.jsの非同期環境でうまく動作することを目的として設計されています。
- モデルを定義して操作することで、MongoDBのコレクション/ドキュメントを操作できます
公式サイト: https://mongoosejs.com/
dotenv
- 環境変数を定義するときに使う
- mongoDBのURLとかgitにあげたらやばいので、、
参考サイト
nodemon
デフォルトの設定だとファイルを書き換えるたびに node app.js
としないと更新されない。さすがにそれは面倒なので「ファイルが更新されるたびに自動的にサーバーを再起動してくれるツール」というのがnodemonです。
参考サイト: https://qiita.com/mitsuhiro_K/items/429ca479b4e191bfea4d
環境変数の設定
.envファイルを作成し、ポート番号とMongoDBを設定しましょう。
PORT = 5000
DB_URL = MongoDBのURL
MongoDBの設定方法はこちらをご参照ください、、
https://reffect.co.jp/node-js/mongodb-cloud#MongoDB_Cloud
app.js の作成
プロジェクト直下に app.js を作成し、インストールしたパッケージを読み込みましょう。
app.js は サーバーのスターティングポイントになります
// 必要なモジュールのインポート
require("dotenv").config();
const express = require("express");
const mongoose = require("mongoose");
const app = express(); // express のインスタンス化
const port = process.env.PORT || 5000; // ポート番号の指定
// MongoDB接続
mongoose
.connect(process.env.DB_URL)
.then(() => console.log('データベース接続に成功しました'))
.catch((err) => console.log(err));
app.listen(port, () => console.log(`server running at localhost:${port}`)); // サーバー立ち上げ
サーバーを起動してみる
ここまで出来たらサーバーの立ち上げてみましょう。
先ほどインストールした nodemon を使って サーバーを起動できるように package.json を書き換えましょう。
package.json
"scripts": {
"dev": "nodemon app.js"
},
npmスクリプトを上記のように書き換えることで以下コマンドで立ち上げることが出来ます。!
npm run dev
localhost:5000 にアクセスすると以下スクショのような表示になっており、コンソールに
- server running at localhost:5000
- データベース接続に成功しました!
が出ていれば一旦大丈夫です!
(エラーが出てるのは一旦気にしないでください)
Controller と Route の設定
この項目では以下のことを行います
- Controller の作成
- Route の設定
- 設定したAPIのエンドポイントを叩く
※DBとの接続はまだ行いません!!
Route の設定
routesというディレクトリを作成し、route.js を作成しましょう。
以下のような構文で記述することができます。
router.HTTPメソッド("エンドポイント", 実行する処理);
CRUD な処理を全て記述しておきましょう。
routes/route.js
const express = require('express');
const router = express.Router();
const API = require('../controllers/controller.js');
router.get('/', API.fetchAllPost); // 全件取得
router.get('/:id', API.fetchPostDetail); // 詳細取得
router.post('/', API.createPost); // 投稿
router.patch('/:id', API.updatePost); // 更新
router.delete('/:id', API.deletePost); // 削除
module.exports = router;
Controller を作成
先ほどルーティングを設定しましたが現状だとそれに対応するメソッドが存在しません。Controller を作成し、それぞれのエンドポイントに対応するメソッドを定義していきましょう。
controllers/controller.js
module.exports = class API {
static async fetchAllPost(req, res) {
try {
res.send('全件取得に成功!!');
} catch (err) {
res.status(404).json({ message: err.message });
}
}
static async fetchPostDetail(req, res) {
try {
res.send('詳細取得に成功!!');
} catch (err) {
res.status(404).json({ message: err.message });
}
}
static async createPost(req, res) {
try {
res.send('投稿に成功!!');
} catch (err) {
res.status(404).json({ message: err.message });
}
}
static async updatePost(req, res) {
try {
res.send('更新に成功!!');
} catch (err) {
res.status(404).json({ message: err.message });
}
}
static async deletePost(req, res) {
try {
res.send('削除に成功!!');
} catch (err) {
res.status(404).json({ message: err.message });
}
}
};
Controller を app.js に追記します。
app.js
const posts = require('./routes/route');
app.use('/api/posts', posts);
参考: https://expressjs.com/ja/guide/routing.html
Postman で動作確認
ここまできたら一度Postman で指定したエンドポイントにアクセスしてみましょう。
http://localhost:5000/api/posts
http://localhost:5000/api/${id}
※現時点では ${id} は適当な数字を入れても処理は走ります。
Modelを作成してMongoDBと接続する
先ほど作成した Controller を Model と接続していきましょう。
models でスキーマを定義していきます。
1つの投稿が持ってるプロパティと、型を定義していく。
models の作成
models/model.js
const mongoose = require('mongoose');
const PostSchema = mongoose.Schema({
title: { type: String, required: true },
content: { type: String, required: true },
created_at: { type: Date, default: Date.now },
});
// スキーマからPostモデルを生成する
module.exports = mongoose.model('Post', PostSchema);
参考
https://mongoosejs.com/docs/guide.html
https://mongoosejs.com/docs/models.html
Controllers と Models を繋ぎ込む
先ほど作成した Model を Controller で呼び出しましょう。
スキーマから生成したモデルが持つメソッドがあるので、対応するメソッドを呼び出します。
例えば新しくPOSTを作成するときは、 create()
というメソッドがあるので呼び出してみましょう。
controllers/controller.js
const Post = require('../models/model'); // 追記
module.exports = class API {
// 省略
static async createPost(req, res) {
try {
const post = req.body;
try {
await Post.create(post);
res.status(201).json({ message: '投稿に成功!!' });
} catch (err) {
res.status(400).json({ message: err.message });
}
} catch (err) {
res.status(404).json({ message: err.message });
}
}
// 省略
};
Postman でPOSTの処理を確認してみましょう。
無事に投稿できました!!
MongoDBの中にも保存されていますね。
他の処理も Mongoose の公式ドキュメントを参考に、それぞれに対応するメソッドに書き換えていきます。
公式: https://mongoosejs.com/docs/api.html#Model
controllers/controller.js
static async fetchAllPost(req, res) {
try {
const posts = await Post.find();
res.status(200).json(posts);
} catch (err) {
res.status(404).json({ message: err.message });
}
}
static async fetchPostDetail(req, res) {
const id = req.params.id;
try {
const post = await Post.findById(id);
res.status(200).json(post);
} catch (err) {
res.status(404).json({ message: err.message });
}
}
static async createPost(req, res) {
// さっき書いたから省略
}
static async updatePost(req, res) {
const id = req.params.id;
const newPost = req.body;
try {
await Post.findByIdAndUpdate(id, newPost);
res.status(201).json({ message: 'post updated' });
} catch (err) {
res.status(400).json({ message: err.message });
}
}
static async deletePost(req, res) {
const id = req.params.id;
try {
const result = await Post.findByIdAndDelete(id);
res.status(201).json({ message: 'post deleted' });
} catch (err) {
res.status(400).json({ message: err.message });
}
}
※ ちなみに /${id}
にあたる部分は投稿時に自動生成される id をのことです
他の処理も書き換えて見て Postman で動作確認して見ましょう。
最後に
長々と書いてしまいましたが以上になります!!
業務ではフロントにしか触れてないのでサーバー側の技術は新鮮でした。
Javascript で記述できる点や、 MongoDBが直感的に記述できたのでよかったです。
参考サイト
https://mongoosejs.com/
https://www.npmjs.com/package/dotenv
https://qiita.com/mitsuhiro_K/items/429ca479b4e191bfea4d
https://maku77.github.io/nodejs/env/dotenv.html
https://mongoosejs.com/docs/guide.html
https://mongoosejs.com/docs/models.html