WEB开发: Node.js路由之由浅入深(三)自动配置路由 - 全栈工程师入门

server/2024/12/19 21:07:44/

前面我们一起学习了Node.js路由的两个进阶,

(1)WEB开发: Node.js路由之由浅入深(一) - 全栈工程师入门

(2)WEB开发: Node.js路由之由浅入深(二)自动路由 - 全栈工程师入门

在第二进阶中,我们已经通过将路由结构模块化,实现了比较方便的而路由方法。

一、进阶分析

但是,你会发现这个文件需要手工去编写:


/project/routesroutesConfig.js

对,就是这个routesConfig.js,每次新增或者删除、修改路由的控制文件,可能都要更改这个文件。

它的内容是这样的:

// routesConfig.js
module.exports = [{ method: 'get', path: '/auth/login', controller: 'authController', action: 'login' },{ method: 'get', path: '/user/:id', controller: 'userController', action: 'getUserById' },{ method: 'post', path: '/product', controller: 'productController', action: 'createProduct' },{ method: 'post', path: '/auth/login', controller: 'authController', action: 'login' }// 更多路由...
];/*
@method: 对应来自 访问端 的RESTful API 方法 
@path: 定义来自访问端的路径
@controller 根据method 和 path  来定位使用什么控制器
@action 定义使用控制器中的什么函数
*/

仔细观察你会发现,这里面的内容,和我们控制器以及控制器内的配置是存在对应关系的,也就是

method: 这个是api进来的请求方式

controller: 这个是我们控制器的文件名

action: 这个是我们控制器内的函数名

唯一一个没有对应关系的是 path。

那么搞清楚这个关系,就好办了。

二、更改控制器

既然path和控制器的文件名、内容都无关,那么我们是否可以将这个关系写到控制器内,然后通过自动读取文件夹、解析文件内容的方式,来自动生成这个routesConfig.js文件呢?

答案当然是可以的。

所以我们只需要修改下面两部分:

第一部分,修改控制器的写法,比如userController.js的写法,改成这样:


// userController.js
module.exports = {get: {getUserById: {path: '/user/:id',fn: (req, res) => {const userId = req.params.id;res.send(`User ID: ${userId}`);},}},post: {getUserById: {path: '/user/:id',fn: (req, res) => {const userId = req.params.id;res.send(`User ID: ${userId}`);}},}// 更多方法...
};

看到了吗 ,我们把控制器分成了 get 和post 两类,当然你也可以加put  delete。

然后我们这里面加入了 path。 也就是说当你写控制器的时候,你就顺手将path 写进去了,不需要去写其他的文件。fn就是我们之前的action。

所以这个路由的get调用就是: 控制器.get.getUserById.fn() ,路径就是: 控制器.get.getUserById.path

三、更改app.js

所以我们需要更改一下app.js 的动态路由方法,改动后如下:

// 动态加载路由
routesConfig.forEach(route => {const controller = require(`./controllers/${route.controller}`);  // 动态加载控制器app[route.method](route.path, controller[route.method][route.action].fn);  // 将路由与控制器方法绑定console.log('for review route:', route.method, route.path, controller[route.method][route.action].fn)});

看到了吗,route.path, controller[route.method][route.action].fn 对应了我上面的解释。

四、自动生成路由配置

到这里,整个路由逻辑完成了,但是我们需要自动生成路由配置文件,而不是手写。

所以我们需要增加一个routesConfigMake 的脚本: rcMake.js:

const fs = require('fs');
const path = require('path');const rcMake = () => {// 定义 controllers 目录const controllersDir = path.join(__dirname, 'controllers');// 获取 controllers 目录下的所有文件(同步方法)let files;try {files = fs.readdirSync(controllersDir);} catch (err) {console.error('无法读取 controllers 目录:', err);return;}// 用于保存所有路由信息的数组const routes = [];// 逐一处理每个文件files.forEach(file => {const filePath = path.join(controllersDir, file);const fileName = path.basename(file, '.js'); // 去掉文件扩展名// 只处理 .js 文件if (path.extname(file) === '.js') {let controller;try {controller = require(filePath);} catch (err) {console.error(`无法加载文件 ${file}:`, err);return;}// 遍历 controller 中的 HTTP 方法(get, post 等)Object.keys(controller).forEach(method => {const methodRoutes = controller[method];// 遍历每个方法的路由Object.keys(methodRoutes).forEach(action => {const route = methodRoutes[action];routes.push({method: method,path: route.path,controller: fileName,action: action});});});}});// 生成 routes.js 文件的内容const routesContent = `// routes.js\nmodule.exports = ${JSON.stringify(routes, null, 2)};\n`;// 将生成的内容写入 routes.js 文件(同步方法)try {fs.writeFileSync(path.join(__dirname, '/routers/routesConfig.js'), routesContent);console.log('routesConfig.js 文件已生成');} catch (err) {console.error('写入 routesConfig.js 文件失败:', err);}
};module.exports = rcMake;

这个脚本放在和app.js 中 ,在app.js的最开始调用,自动将我们控制器内的配置写在这个配置文件中,执行后生成routesConfig.js文件,内容如下:

// routes.js
module.exports = [{"method": "get","path": "/auth/login","controller": "authController","action": "login"},{"method": "post","path": "/auth/login","controller": "authController","action": "login"},{"method": "get","path": "/product","controller": "productController","action": "createProduct"},{"method": "post","path": "product","controller": "productController","action": "createProduct"},{"method": "get","path": "/user/:id","controller": "userController","action": "getUserById"},{"method": "post","path": "/user/:id","controller": "userController","action": "getUserById"}
];

请注意,这时候你必须所有的控制器都按照我前面提到的方式来改写,这里包括了 get 和post 两类,其他自己可以加。,app.js 会自动调用这个配置的。

五、更新app.js

最后,app.js 需要加上这个脚本:

const express = require('express');
const app = express();//加上脚本 自动生成路由配置文件
const rcMake = require('./rcMake.js')
rcMake()const routesConfig = require('./routers/routesConfig');  // 导入路由配置文件// 动态加载路由
routesConfig.forEach(route => {const controller = require(`./controllers/${route.controller}`);  // 动态加载控制器app[route.method](route.path, controller[route.method][route.action].fn);  // 将路由与控制器方法绑定console.log('for review route:', route.method, route.path, controller[route.method][route.action].fn)});// 启动服务
const port = 3000;
app.listen(port, () => {console.log(`Server is running on port ${port}`);
});

好了,这样,你的工作就只需要关注在写控制器上,而无需关注路由配置,因为路由配置都自动化了。这样多方便?

需要完整的项目文件,请给我留言。


http://www.ppmy.cn/server/151540.html

相关文章

JAVA入门:使用IDE开发

JAVA入门:使用IDE开发 什么是IDE IDE(Integrated Development Environment,集成开发环境)是一种软件应用程序,它为程序开发、软件设计、项目管理等提供全面的设施。 简单来说就是简化开发过程,让编程更加方便。 IDEA 业界公认最好用的JAVA IDE 安装IDEA 打开IDEA官…

禁用硬件合成 (Hardware Composer, HWC)

要禁用硬件合成 (Hardware Composer, HWC),通常需要根据具体的设备平台和系统环境选择适合的方法。以下是通用的解决方案: 1. 修改系统属性 在 Android 系统中,可以通过设置系统属性来禁用 HWC 合成: a. 使用 setprop 命令临时禁…

barin.js(十四)GRU实战教程 - 文本情感分析之有害内容检测

系列文章: (一):brain.js概要介绍(二):项目集成方式(三):手把手教你配置和训练神经网络(四):利用异步训练和交叉验证来优…

C# OnnxRuntime Gaze-LLE 凝视目标估计,通过利用冻结的DINOv2编码器的特征来简化注视目标估计,预测一个人在场景中看的位置。

目录 说明 效果 ​编辑模型信息 det_face.onnx gazelle_dinov2_vitl14_inout_1x3x448x448_1xNx4.onnx 项目 代码 下载 参考 说明 github地址:https://github.com/fkryan/gazelle This is the official implementation for Gaze-LLE, a transformer appro…

C#核心(17)密封类

前言 我们先前已经学完了继承中的大部分知识,今天我们就来学习最后一个知识点,密封类。 其实我不喜欢叫他密封类,我比较喜欢叫他结扎。 在Unity中,C#的密封类(sealed class)是一个重要的概念&#xff0c…

2019陕西ICPC-Grid with Arrows

Grid with Arrows 题意 一个总规模为n m 的矩阵,矩阵上的每个位置有其下一位置的信息,询问是否存在一种解法从某一点出发,使得整个矩阵的每个位置都被访问到,如果越界或者遇到重复访问位置的解法被认为失败。 解决思路 求是否…

射频测试入门学习(三)——程控仪器是怎样和电脑连接通信的

目录 一、程控仪器需要哪些条件 二、可程控仪器 三、专业的仪器通信软件、驱动 四、编程语言 五、电脑控制仪器条件汇总 六、仪器指令查询 七、结语 一、程控仪器需要哪些条件 1、需要具备硬件条件(可程控的仪器、个人计算机(PC)) 2、专业的仪器通信软件、驱动 3、…

Git-分支(branch)常用命令

分支 我们在做项目开发的时候,无论是软件项目还是其他机械工程项目,我们为了提高效率以及合理的节省时间等等原因,现在都不再是线性进行,而是将一个项目抽离出诸进行线,每一条线在git中我们就叫做分支,bran…