9.1 Router 层是什么Router 层负责把 URL 和 HTTP 方法映射到对应的 Controller 方法。Express 的Router可以把路由分组管理而不是把所有路由都堆在app.ts里。9.2 基本用法最简单的写法import{Router}fromexpress;import{ProjectController}from/controllers/project/project-controller.js;exportfunctioncreateProjectRouter(controller:ProjectController){constrouterRouter();router.get(/projects,controller.list);router.get(/projects/:id,controller.get);router.post(/projects,controller.create);router.put(/projects/:id,controller.update);router.delete(/projects/:id,controller.remove);returnrouter;}用前缀分组同一个模块的路由共享前缀exportfunctioncreateProjectRouter(controller:ProjectController){constrouterRouter();// 所有路由自动带 /projects 前缀router.get(/,controller.list);// GET /projectsrouter.get(/:id,controller.get);// GET /projects/:idrouter.put(/,controller.create);// PUT /projectsrouter.put(/:id,controller.update);// PUT /projects/:idrouter.delete(/:id,controller.remove);// DELETE /projects/:idreturnrouter;}然后在父路由里挂上前缀router.use(/projects,createProjectRouter(projectController));9.3 路由的层级组织按版本 按模块大型项目推荐这样组织src/routers/ ├── index.ts# 根路由挂载所有子路由├── api-router.ts# /api 总路由├── v1/ │ └── index.ts# /api/v1 版本路由├── v2/ │ └── index.ts# /api/v2 版本路由├── project/ │ └── project-router.ts# 项目管理模块路由└── user/ └── user-router.ts# 用户管理模块路由根路由src/routers/index.tsimport{Router}fromexpress;import{createApiRouter}from./api-router.js;exportfunctioncreateRouter(){constrouterRouter();// API 路由router.use(/api,createApiRouter());// 健康检查不放在 /api 下也行router.get(/health,(_req,res){res.json({status:ok});});returnrouter;}API 总路由src/routers/api-router.tsimport{Router}fromexpress;import{createV1Router}from./v1/index.js;exportfunctioncreateApiRouter(){constrouterRouter();router.use(/v1,createV1Router());// router.use(/v2, createV2Router()); // 以后加 v2 版本returnrouter;}版本路由src/routers/v1/index.tsimport{Router}fromexpress;importtype{AppModels}from/bootstrap.js;import{ProjectController}from/controllers/project/project-controller.js;import{UserController}from/controllers/user/user-controller.js;import{ProjectService}from/services/project/project-service.js;import{UserService}from/services/user/user-service.js;import{createProjectRouter}from../project/project-router.js;import{createUserRouter}from../user/user-router.js;exportfunctioncreateV1Router(models:AppModels){constrouterRouter();// 组装各模块的 Controller 和 ServiceconstprojectControllernewProjectController(newProjectService(models.projects),);constuserControllernewUserController(newUserService(models.users),);// 挂载各模块路由router.use(/projects,createProjectRouter(projectController));router.use(/users,createUserRouter(userController));returnrouter;}模块路由src/routers/project/project-router.tsimport{Router}fromexpress;importtype{ProjectController}from/controllers/project/project-controller.js;exportfunctioncreateProjectRouter(controller:ProjectController){constrouterRouter();router.get(/,controller.list);router.get(/:id,controller.get);router.put(/,controller.create);router.put(/:id,controller.update);router.delete(/:id,controller.remove);returnrouter;}9.4 为什么在版本路由里组装 Controller你可能注意到了Controller 和 Service 的组装new放在了版本路由里而不是bootstrap.ts。两种做法都可以做法优点缺点bootstrap 里组装全部统一管理所有依赖一目了然bootstrap 文件会越来越长各版本路由里组装每个版本自己决定用哪些模块不同版本可以有不同实现依赖分散在多处中小项目推荐放 bootstrap 统一管理大项目可以按模块/按版本分散。本教程为了简单清晰采用集中在 bootstrap 组装的方式见第 10 篇。9.5 路由级中间件除了全局中间件还可以给某个路由或某组路由单独加中间件。给单个路由加router.get(/projects,authMiddleware,controller.list);给一组路由加constrouterRouter();// 这些不需要登录router.post(/login,authController.login);router.post(/register,authController.register);// 下面的都需要登录router.use(authMiddleware);router.get(/projects,controller.list);router.get(/projects/:id,controller.get);给子路由加// 管理后台的路由都需要管理员权限router.use(/admin,requireAdmin,createAdminRouter(adminController));路由级中间件的执行顺序是先执行全局的再依次执行路由上挂载的。9.6 路由参数的类型req.params里的参数都是字符串哪怕你定义的是数字 ID。router.get(/projects/:id,(req,res){console.log(typeofreq.params.id);// string// 用的时候要转成数字constidNumber(req.params.id);});这也是为什么我们在 Controller 里用Number(req.params.id)转一下。9.7 常见的路由组织问题❌ 把业务逻辑写在路由文件里// 反面例子router.get(/projects,async(req,res){// 写了一堆业务逻辑constdbawaitgetDB();constlistawaitdb.query(SELECT * FROM projects);res.json({status:0,data:list});});路由文件只负责 URL 映射业务逻辑放在 Controller 和 Service。❌ 路由层级太深/api/v1/admin/settings/notification/email/template/list层级太多不便于理解和查找。一般控制在 3-4 层以内比较合适。❌ 同一个接口有多种写法// 一会用 get一会用 post参数位置也不统一router.get(/project/list,...);router.post(/project/add,...);router.get(/project/detail/:id,...);保持风格一致要么都 RESTful要么都用动词后缀。9.8 小结Router 层负责 URL 到 Controller 的映射按版本 按模块组织路由结构清晰路由文件只写映射关系不写业务逻辑Controller 可以在 bootstrap 集中组装也可以在各路由里分散组装路由级中间件用于给部分接口加特定功能如鉴权、限流
企业数字化 ERP 产品动态
相关推荐
vector的模拟实现与迭代器失效 目录 一,简言
二,构造函数与析构函数
1,默认构造函数和拷贝构造函数
2,迭代器区间构造函数
3,填充构造函数
4,析构函数
5,构造时的匹配错误:
三,赋值重载
四&… · 2026/9/24 17:28:36
同城生活小程序开发:未开通业务入口怎么按配置隐藏 同城生活小程序首期只开外卖时,若首页仍展示跑腿、团购等未开通入口,用户点进去空白或报错,转化与信任双损。宜在配置层做业务开关,端上按开关渲染菜单,而不是改代码发版才能藏入口。本文用代码深讲说明配置模型、端侧… · 2026/9/24 17:28:36
数字化工业软件全面AI解决方案 重塑从设计、仿真到PLM的空华品国邮智能研发新范式产品越来越复杂,合规、协同压力拉满,传统研发陷入效率低、周期长、成本高的困境怎么办?西门子数字化工业软件全面的 AI 解决方案,重塑从设计、仿真到 PLM 的全生命周期智能研发新… · 2026/9/24 17:28:29
IWOA-BILSTM与BILSTM对比:时间序列预测的超参数优化实践 简介:面向时序预测建模与算法对比需求的 MATLAB 开发者,这份资源提供了改进鲸鱼算法优化双向长短期记忆网络(IWOA-BILSTM)与标准 BILSTM 的完整对比实现。资源聚焦迭代次数、隐藏层节点数、学习率与正则化参数四个核心超参数的自动… · 2026/9/24 19:16:50
SpringBoot天气预报系统开发实战:API对接与缓存策略详解 1. 项目整体设计与技术选型思路
1.1 为什么选SpringBoot做天气预报系统 说实话,每年到了毕业设计或者课程综设的季节,天气预报管理系统几乎是Java方向的“常青树”题目。它看起来不难,但用户注册登录、城市管理、天气数据展示、定时刷新这些… · 2026/9/24 19:16:50
Spring Boot+Vue实现小区家政预约平台:从设计与实现到部署运维 从最开始接到这个"小区家政服务预约平台"的需求,我心里其实很清楚,这类项目表面上是一个简单的前后端应用,真正磨人的地方在后面——预约的时间冲突、服务人员的排班、用户爽约、平台方对订单的管控,任何一个点处理不好… · 2026/9/24 19:16:50
改进鲸鱼算法IWOA优化BILSTM:时间序列预测与Matlab实现 简介:这份资源是一套面向时序预测的IWOA-BILSTM/BILSTM对比建模代码。适用于需要利用改进鲸鱼算法优化双向长短期记忆网络的研究者、工程师或相关专业学生。通过同时提供两种模型,可直接对比改进前后预测效果,常用于气象、金融、能源等领域的… · 2026/9/24 19:16:50
工控机离线安装.NET Framework 3.5/4.8完整指南:DISM命令实战 干工控这行的朋友,十有八九都遇到过这种场景:现场一台德承工控机DA-1000,系统是Windows 10 IoT Enterprise,软件装了一多半,双击安装包忽然弹出“此程序需要.NET Framework 3.5”,或者软件装上去了… · 2026/9/24 19:16:50
Markor 深度使用指南:纯文本笔记与 todo.txt 待办管理实践 1. 为什么我最终把主力笔记应用换成了 Markor用了七八年 Android 手机,笔记类应用我装过不下二十款。从云同步的到纯本地的,从富文本的到纯 Markdown 的,几乎每一类都深度用过至少三个月。换来换去,最后留在桌面上当主力的是 Mark… · 2026/9/24 19:16:31
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44