Express 安裝
安裝只要兩個步驟:
1. $ npm init
2. $ npm install express --save
這樣就安裝完成了
建立 app
開始使用 Express,首先要先建立一個 js 檔,引入 express 到你的檔案當中
const express = require('express');
引入的 express 會是一個 function,當我們去執行這個 function,就可以建立一個 app
const express = require('express');
const app = express(); // 執行這個 function,就可以建立一個 app
const app2 = express(); // 執行兩次 function,可以建立兩個 app
指定 port
我們可以指定一個 port 給這個 app,並在最後加上一個監聽器來監聽這個 port
const express = require('express');
const app = express();
const port = 3000; // 指定一個 port 給這個 app
app.listen(port, () => { // 加上一個監聽器來監聽這個 port
console.log(`Example app listening at http://localhost:${port}`)
})
處理 request / response
在 Express 要設定 處理 request / response 非常簡單
以 GET method 為例:
- 使用 get() 函式,可以讓我們傳入兩個參數:
- 第一個參數:URL 的目錄
- 第二個參數:call back function
app.get('/', (req, res) => {
res.send('Hello World!'); // 設定 response
})
完整的檔案內容:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello World!');
})
app.get('/hello', (req, res) => {
res.send('Hello man');
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
在 CLI 上面輸入 node <檔名>
,就可以啟動這個 Server 了
- 當網址輸入 localhost:3000 時,網頁上顯示
Hello World!
- 當網址輸入 localhost:3000/hello 時,網頁上顯示
Hello man
如果要接收 URL 上面不確定的資料,比如說 id,我們可以這樣寫
app.get('/:id', (req, res) => { // 用 : 來表示這是不確定的參數
const id = req.params.id // 用 req.params 來取得上面設定的參數
})
Express 基本架構 MVC
MVC 架構:
- Model:負責管理資料
- View:負責管理畫面的顯示
- Controller:Model 跟 View 之間的協調者
當 Controller 收到 request 以後,會先到 Model 拿資料,Controller 拿到資料之後會將資料交給指定的 View,等到 View 將資料與畫面組合起來之後會拿回來給 Controller,最後再由 Controller 回覆 response
建立 View
在開始建立 View 之前,要先安裝 Template Emgine(模板引擎),這邊選用 EJS 這個模板引擎
npm install ejs
安裝完成後,要在檔案裡面設定參數
app.set('view engine', 'ejs');
預設的目錄會是 views
,所以要在專案資料夾之中,新建一個資料夾叫做 views
,將所有的 .ejs 檔放在這個資料夾底下
假設我們在 views
底下新建一個檔案叫做 hello.ejs
那我們要叫 express 去 render hello.ejs 這個檔案時,可以使用 render() 這個函式
render() 有兩個參數:
- 要 render 的檔案名稱 (副檔名 .ejs 可以審略)
- 要帶入的資料(用物件包起來)
app.get('/hello', (req, res) => { // 接收 URL 為 ..../hello
res.render('hello'); // 叫 express 去 render views 底下的 hello.ejs 這個檔案
})
如果要將資料帶入 todo.ejs 可以這樣寫:
const express = require('express');
const app = express();
const port = 3000;
app.set('view engine', 'ejs');
let todos = ['first todo', 'second todo', 'third todo'];
app.get('/todos', (req, res) => {
res.render('todos', {
todos: todos
})
})
app.get('/todos/:id', (req, res) => {
const id = req.params.id
res.render('todo', {
todo: todos[id]
})
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
在 .ejs 的檔案當中,要使用 JavaScript 的程式碼,要使用 <% %>
這個標籤來夾住,如果是要印出資料,可以使用 <%= %>
放要輸出的變數
// 接收一個 todos = ['first todo', 'second todo', 'third todo'] 的陣列
<h1>Todo</h1>
<ul>
<% for (let i = 0; i < todos.length; i++) { %>
<li><%= todos[i] %></li>
<% } %>
</ul>
建立 Model
先在專案資料夾底下,新建一個 models
資料夾,將所有跟 model 相關的檔案都放在這個資料夾底下
model 是負責管理 data 的,所以假設剛剛的 todos 陣列要放在 model 底下管理,可以把它寫成下面這樣:
const todos = [
'first todo', 'second todo', 'third todo'
]
const todoModel = {
getAll: () => {
return todos
},
get: id => {
return todos[id]
}
}
module.exports = todoModel
建立 Controller
先在專案資料夾底下,新建一個 controllers
資料夾,將所有跟 controller 相關的檔案都放在這個資料夾底下
將 Model 跟 View 之間的協調,交給 controller 來做
const todoModel = require('../models/todo'); // 引入 model
const todoController = {
getAll: (req, res) => {
const todos = todoModel.getAll() // 把 todos 用 getAll 拿出來
res.render('todos', {
todos
})
},
get: (req, res) => {
const id = req.params.id
const todo = todoModel.get(id)
res.render('todo', {
todo
})
}
}
module.exports = todoController;
當我們將 Model 跟 View 之間的協調,交給 controller 來做之後,就可以將一開始 app Server 的檔案改得更加簡潔,讓這份檔案成為專門處理路由的檔案
const express = require('express');
const app = express();
const port = 3000;
const todoController = require('../controllers/todo');
app.set('view engine', 'ejs');
app.get('/todos', todoController.getAll)
app.get('/todos/:id', todoController.get)
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
這樣就做完基本的 MVC 架構了,下面我們要來將原本放在 model 的資料,換成放在「資料庫」,並實作 node.js 跟 mySQL 的溝通
(注意是 node.js 跟 mySQL 的溝通,不是 express 跟 mySQL 的溝通,因為不用 express,node.js 本身就可以跟 mySQL 的溝通)
node.js 跟 mySQL 溝通
第一步:安裝套件
npm install mysql
接下來建立一個 db.js 處理 node.js 跟 mySQL 的溝通
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
module.exports = connection;
回到 app Server 的檔案,將 db.js 引入,並且在 Server 跑起來之後,連線到 mySQL
const express = require('express');
const db = require('./db') // 將 db.js 引入
const app = express();
const port = 3000;
const todoController = require('../controllers/todo');
app.set('view engine', 'ejs');
app.get('/todos', todoController.getAll)
app.get('/todos/:id', todoController.get)
app.listen(port, () => {
db.connect() // 在 Server 跑起來之後,連線到 mySQL
console.log(`Example app listening at http://localhost:${port}`)
})
再來要來改我們的 model,將 db.js 引入,並且把回傳資料的部分用 call back function 來改寫
使用 connection.query() 帶入的參數為:
- 第一個參數:sql 指令 (參數用 ? 代替)
- 第二個參數:一個陣列(裡面放入要取代 ? 的值)
- 第三個參數:call back function
在此範例中因為將 connection 引入後賦值到 db,所以上面寫的是 db.query()
const db = require('../db')
const todoModel = {
getAll: (cb) => {
db.query(
'SELECT * FROM todos',
(err, results) => {
if (err) return cb(err);
cb(null, results); // 因為 cb 的第一個參數放 error,所以如果沒有錯誤第一個參數要傳 null
}
);
},
get: id => {
db.query(
'SELECT * FROM todos WHERE id = ?', [id],
(err, results) => {
if (err) return cb(err);
cb(null, results);
}
);
}
}
module.exports = todoModel
因為從原本的同步變成非同步了,所以 controller 也要做處理
const todoModel = require('../models/todo'); // 引入 model
const todoController = {
getAll: (req, res) => {
todoModel.getAll((err, results) => {
if (err) return console.log(err);
res.render('todos', {
todos: results
})
})
},
get: (req, res) => {
const id = req.params.id
todoModel.get(id, (err, results) => {
if (err) return console.log(err);
res.render('todo', {
todo: results[0] // 因為就算只有一個結果 results 一樣會是一個陣列,所以要用 [0] 來取值
})
})
}
}
module.exports = todoController;
如此一來,我們就完成了基本的 MVC 架構(mySQL 版),接下來會在下篇文章提到更多 Express 的重要概念。