[Node.js]Node.js+ExpressでMVCっぽく書いてみる
2019.04.25
こんにちは千田です。
さて、今回はタイトルの通り「Node.js+ExpressでMVCっぽく」書いてみようと思います。
初めてExpressに触れた時、ほとんどのコードをrouterに直接書いてしまっていて、もう少しうまく書けないかなーと思った事がきっかけです。
そもそもMVCモデルとは
アプリケーションをM(Model)V(View)C(Controller)の3つに分割して構築するお作法の事です。
以下、 Wikipediaより
・Model:アプリケーションデータ、ビジネスルール、ロジック、関数
・View:グラフや図などの任意の情報表現
・Controller:入力を受け取りmodelとviewへの命令に変換する
Expressとは
公式サイトより
Express は、Web アプリケーションとモバイル・アプリケーション向けの一連の堅固な機能を提供する最小限で柔軟な Node.js Web アプリケーション・フレームワークです。
上記の通り、Expressはあくまで最小限な機能を提供するものなので、モジュールを組み合わせて柔軟に構築する事ができます。
よく見る書き方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | var express = require('express'); var router = express.Router(); var mysql = require('mysql'); var db = require('../config/db'); router.get('/users/index', (req, res, next) => { var sql = 'select * from users'; try { const connection = mysql.createConnection(db); connection.connect(); connection.query(sql, (error, results, fields) => { if (error == null) { res.render('index.ejs', { content: results }); }else{ throw(error); } } ); connection.end(); } catch(e) { res.render('index.ejs', { content: {error: e}, }); } }); |
Expressで書かれたコードを調べている時、よく見かけるのはこんな感じのコードかと思います。
当然、上記のコードでも実行する上で問題は無いのですが、量が増えてくるとコードの見通しが悪くなりそうです。
他の言語なんかでMVCフレームワークを用いた開発をした事がある方には違和感もあるのかなと。
千田も元々CakePHPとかをやっていたクチなので、もう少し整理できないものかなーと思いました。
やりたい事
Expressを使っていわゆるMVCフレームワークっぽく書いてみたい。
やってみる
という事で早速書いていきます。今回はユーザー情報を表示するページを想定して書いてみます。
前提条件
・Node.jsのバージョン: 10.15.1
・Expressのバージョン: 4.16.0
・データベース: MySQL 5.7
ディレクトリ構成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ├── app.js ├── bin │ └── www │ ├── config │ └── db.js │ ├── controllers │ └── UserController.js │ ├── models │ └── Users.js │ ├── views │ └── index.ejs │ ├── routes │ └── routes.js ├── package.json ├── public |
express-generatorで初期構築したあとに
・config
・controllers
・models
を追加しています。
ルーティング設定
routes/routes.js
1 2 3 4 5 6 7 8 | var express = require('express'); var router = express.Router(); var userController = require('../controllers/UserController') router.get('/users', userController.doGetUser); router.post('/users/regist', userController.doRegistUser); module.exports = router; |
ルーティングはroutes.jsに書いています。
あくまでHTTPリクエストのエンドポイントに対して、どのモジュールで処理をするかだけを書くようにしています。
3行目でいわゆるcontrollerを読み込んでいます。
Controllerを書く
controllers/UserController.js
1 2 3 4 5 6 7 8 9 10 11 | const express = require('express'); const Users = require('../models/Users'); const Views = '../views/' module.exports = { doGetUser: function (req, res, next) { Users.getUser(id).then((result) => { res.render(Views + 'index.ejs',{users: result}); }); } } |
Controllerではrouterから受け取ったリクエストに対してModelでの処理を実行し、結果をViewに渡しています。
2行目でModelを読み込んでいます。
Modelを書く
models/User.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | const mysql = require('mysql'); const db = require('../config/db'); const table = 'users'; module.exports = { getUser: function () { return new Promise ((resolve, reject) => { const con = mysql.createConnection(db); con.query( `select id, name, date_format(birthdate,"%Y/%m/%d") as birthdate from ${table}`, (err, result, fields) => { if ( err ) { reject(err); } else { resolve(result); } }); con.end(); }); }, } |
ModelではDBから値を取得し、Controllerにそれを返しています。
Viewを書く
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Controllerから受けたデータを用いてレンダリングします。
まとめ
もっといい書き方はあるかと思いますが、上記のようにMVCっぽく分ける事はできたかなと思います。
routerに全ての処理を書いていた時と比べると非常にスッキリしたと思いますし、メンテナンスもしやすくなるのかなと思います。
という訳で、個人的には「Node.js+ExpressでMVCっぽく書いてみる」ことができたと思います。
それではまた!
↓↓↓ぜひチェックしてください
~提供中のヒューマンセンシング技術~
◆人物検出技術
歩行者・来店者数計測やロボット搭載も
https://humandetect.pas-ta.io
◆視線検出技術
アイトラッキングや次世代UIに
https://eyetrack.pas-ta.io
◆生体判定技術
eKYC・顔認証のなりすまし対策を!
https://bio-check.pas-ta.io
◆目検出技術
あらゆる目周りデータを高精度に取得
https://pupil.pas-ta.io
◆音声感情認識技術
会話から怒りや喜びの感情を判定
https://feeling.pas-ta.io
◆虹彩認証技術
目の虹彩を利用した生体認証技術
https://iris.pas-ta.io