马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
前面我们一起学习了Node.js路由的两个进阶,
(1)WEB开发: Node.js路由之由浅入深(一) - 全栈工程师入门
(2)WEB开发: Node.js路由之由浅入深(二)自动路由 - 全栈工程师入门
在第二进阶中,我们已经通过将路由布局模块化,实现了比力方便的而路由方法。
一、进阶分析
但是,你会发现这个文件必要手工去编写:
- /project
- /routes
- routesConfig.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}`);});
复制代码 好了,如许,你的工作就只必要关注在写控制器上,而无需关注路由设置,由于路由设置都自动化了。如很多方便?
必要完备的项目文件,请给我留言。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |