Day21 NodeJS-Express VI

今天的内容是Express部份的最後一哩路:Restful API与应用程序结构化。前几天从前端到後端把Express基础学透透,发现Express并没有对大型专案的开发预先设计一个良好的结构,若未先设计好程序架构,会让开发与维护变得很没有效率 。过去大部份使用.NET MVC进行开发,开发工具建立专案时会自动产生严谨的结构,从来没有想过专案结构设计这件事,是以藉此尝试在Express框架下设计适当的架构。

Restful API

RESTful API是一种符合REST设计风格且透过网际网路传输的API,包含资源的取得、建立、修改与删除,分别对应HTTP协定的GET、POST、PUT及DELETE方法,通常具有简洁的URL、不同的资源传输类型。

Express中的应用程序结构化

由於Express框架具备高度的开发弹性,像是大量的NPM套件及高度自主的程序架构,为了因应更多样的开发需求,开发时也必须要考虑如何将程序进行结构化,除了自行规划架构,在Express中也有提供建立应用程序的工具-express-generator,今天会先说明express-generator的使用方式,再另外尝试自行规划MVC架构。

Express-generator与应用程序结构化

在上课程的时候有发现,因为时间久远的关系,使用express-generator的方法也不太一样,分成旧版(Node.js 8.2.0版本以前)与新版(Node.js 8.2.0版本以後)说明。

旧版流程

  1. 使用npm install以全域方法安装express-generator工具。
  2. 在目标资料夹中,透过express <应用程序名称>可以建立相应的应用程序架构。
  3. npm install指令重建package.json档案所有相依套件,可以在档案列表找到node_module及其中安装好的NPM套件。

新版流程

  1. 在终端机透过npx express-generator指令启用工具(Node.js 8.2.0版本以上),express-generator会在资料夹路径内建立一个包含app.jspackage.json和其他资料夹的应用程序架构。
  2. 使用npm install重建所有相依套件,可以在档案列表找到node_module及其中安装好的NPM套件。

Express-generator所建立的程序架构以app.js为主程序,并建立一个routes的资料夹,用以存放由路由器(express.Router)建立的模组,并在模组中载入函式及定义路由,再以app.use()方法将模组装载至主程序的Path,让程序能具备分层架构,并能依照需求规划路由器模组与其中的函式及路由。

https://ithelp.ithome.com.tw/upload/images/20211006/20139980MRnD0K554C.jpg

规划MVC架构

除了透过express-generator建立以Router分层的架构,也可以运用方法模组、样板等概念建立MVC概念的架构,在前面的文章有规划public资料夹存放静态资料、views资料夹存放页面样板,今天则是将前面练习的主程序中的方法以页面和API分为不同的controller模组,也就是MVC中Controller部份的实现。

https://ithelp.ithome.com.tw/upload/images/20211006/20139980on8CaNX3T8.jpg

  1. 建立controllers资料夹,并建立apiController与htmlController两个*.js档案。
  2. 分别设定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)=>{
    // 删除
  });
}
  1. 在主程序透过require()引用模组,并直接呼叫Controller就可以执行其中的功能。
let httpController = require("./controllers/httpController");
let apiController = require("./controllers/apiController");

httpController(app);
apiController(app);
  1. 测试一下确认功能都与原本的程序码相同,但是就主程序的程序码而言,变得较简洁也较易於维护。

https://ithelp.ithome.com.tw/upload/images/20211006/20139980EDI2jVGgeE.png

小结

脱离了完整规划的.NET後,在使用高度弹性的NodeJS进行开发,才发现应用程序的结构化对於後续的维护很重要,不仅在多人协作的专案中,即使是小专案,没有架构规划最後也可能会变成维护时的程序码地狱。

参考资料

https://expressjs.com/zh-tw/guide/routing.html

Learn and Understand NodeJS [课程]


<<:  Day22:今天来聊一下如何建立及管理 Azure Sentinel 工作区

>>:  #22 IPAPAPI - IP as Picture API

Day 26 Explore monitoring and reporting

Explore Azure service health Provide personalized ...

何谓资讯安全(资安)?

资讯安全在大部份的资安书籍都没有详细的定义,以下是我的 The Effective CISSP: S...

Day 2 (html)

特别叮嘱禁止的错误 1.不要行内包区块 行内:(inline) span 区块:(block) p ...

了解box-model的重要性

了解box-model的重要性 可以把它想成一种容器,它可以容下多少物品的数量多寡或物品装在箱子里...

【Laravel】 MVC 与 专案结构

MVC 何谓MVC? MVC即是一种「网站架构流程」 Route(路由控制) 简介:将接收到的讯息,...