今天的內容是Express部份的最後一哩路:Restful API與應用程式結構化。前幾天從前端到後端把Express基礎學透透,發現Express並沒有對大型專案的開發預先設計一個良好的結構,若未先設計好程式架構,會讓開發與維護變得很沒有效率 。過去大部份使用.NET MVC進行開發,開發工具建立專案時會自動產生嚴謹的結構,從來沒有想過專案結構設計這件事,是以藉此嘗試在Express框架下設計適當的架構。
RESTful API是一種符合REST設計風格且透過網際網路傳輸的API,包含資源的取得、建立、修改與刪除,分別對應HTTP協定的GET、POST、PUT及DELETE方法,通常具有簡潔的URL、不同的資源傳輸類型。
由於Express框架具備高度的開發彈性,像是大量的NPM套件及高度自主的程式架構,為了因應更多樣的開發需求,開發時也必須要考慮如何將程式進行結構化,除了自行規劃架構,在Express中也有提供建立應用程式的工具-express-generator
,今天會先說明express-generator
的使用方式,再另外嘗試自行規劃MVC架構。
Express-generator與應用程式結構化
在上課程的時候有發現,因為時間久遠的關係,使用express-generator
的方法也不太一樣,分成舊版(Node.js 8.2.0版本以前)與新版(Node.js 8.2.0版本以後)說明。
舊版流程
npm install
以全域方法安裝express-generator
工具。express <應用程式名稱>
可以建立相應的應用程式架構。npm install
指令重建package.json
檔案所有相依套件,可以在檔案列表找到node_module
及其中安裝好的NPM套件。新版流程
npx express-generator
指令啟用工具(Node.js 8.2.0版本以上),express-generator
會在資料夾路徑內建立一個包含app.js
、package.json
和其他資料夾的應用程式架構。npm install
重建所有相依套件,可以在檔案列表找到node_module
及其中安裝好的NPM套件。Express-generator所建立的程式架構以app.js為主程式,並建立一個routes的資料夾,用以存放由路由器(express.Router
)建立的模組,並在模組中載入函式及定義路由,再以app.use()
方法將模組裝載至主程式的Path,讓程式能具備分層架構,並能依照需求規劃路由器模組與其中的函式及路由。
除了透過express-generator
建立以Router分層的架構,也可以運用方法模組、樣板等概念建立MVC概念的架構,在前面的文章有規劃public資料夾存放靜態資料、views資料夾存放頁面樣板,今天則是將前面練習的主程式中的方法以頁面和API分為不同的controller模組,也就是MVC中Controller部份的實現。
*.js
檔案。module.exports
為包含相應方法的函式,htmlController存放載入頁面相關的方法,apiController存放處理資料的API。// htmlController
module.exports=(app)=>{
app.get('/', (req, res)=>{
res.render("index");
});
app.post("/personJson", (req, res)=>{
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ a: "Thank you for the JSON data" }));
console.log(req.body.fullName);
});
app.get("/job/:type", (req, res)=>{
res.render("job", {TYPE: req.params.type, QSTR: req.query.qstr});
});
app.post("/person", (req, res)=>{
res.send("Thank you");
console.log(req.body.firstName);
console.log(req.body.lastName);
});
}
// apiController
module.exports = (app) => {
app.get("/api/person", (req, res)=>{
res.json({firstName: "chw", lastName: "k"});
});
app.post("/api/person/:id", (req, res)=>{
// 查詢
});
app.delete("api/person/:id", (req, res)=>{
// 刪除
});
}
require()
引用模組,並直接呼叫Controller就可以執行其中的功能。let httpController = require("./controllers/httpController");
let apiController = require("./controllers/apiController");
httpController(app);
apiController(app);
脫離了完整規劃的.NET後,在使用高度彈性的NodeJS進行開發,才發現應用程式的結構化對於後續的維護很重要,不僅在多人協作的專案中,即使是小專案,沒有架構規劃最後也可能會變成維護時的程式碼地獄。
https://expressjs.com/zh-tw/guide/routing.html
Learn and Understand NodeJS [課程]