其他
设计或重构 NestJS 应用时如何遵循模块化、依赖注入…
在 NestJS 项目中设计模块、实现 Provider、编写异常过滤器、校验 DTO 或集成 Drizzle ORM 时,提供一套可执行的最佳实践规范。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 47/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 49/100 ×0.15
适用场景
设计或重构 NestJS 应用时如何遵循通用
解决思路
- 模块化架构:严格模块封装,每个领域功能独立为一个 @Module();只导出其他模块需要的内容,内部 Provider 保持私有;仅在循环依赖的最后手段使用 forwardRef(),优先重构消除循环;将相关 controller、service、repository 归入同一模块;用 SharedModule 承载日志、配置、缓存等横切关注点。
- 依赖注入:按用例选择正确的 Provider 作用域——DEFAULT 为单例(共享),适用于无状态服务和 repository;REQUEST 为每请求实例,适用于请求级数据(租户、用户上下文);TRANSIENT 为每次注入新实例,适用于有状态工具和按消费者缓存;默认使用 DEFAULT,仅在有理有据时使用 REQUEST 或 TRANSIENT;只用构造函数注入,避免属性注入;用 useClass、useValue、useFactory 或 useExisting 注册自定义 Provider。
- 请求生命周期:理解并遵守 NestJS 请求处理管道顺序:Middleware → Guards → Interceptors (before) → Pipes → Route Handler → Interceptors (after) → Exception Filters;Middleware 处理日志、CORS、body 解析等横切关注点;Guards 做授权与认证检查(返回 true/false);Interceptors 转换响应数据、添加缓存、测量耗时;Pipes 校验并转换输入参数;Exception Filters 捕获并格式化错误响应。
- 错误处理:统一全应用错误响应;继承 HttpException 处理 HTTP 特定错误;创建领域特定异常类(如 OrderNotFoundException);实现全局 ExceptionFilter 统一错误格式;对预期业务逻辑失败使用 Result 模式;绝不静默吞掉异常。
- 校验:在 API 边界强制输入校验;全局启用 ValidationPipe 并设置 transform: true 与 whitelist: true;为所有 DTO 属性添加 class-validator 装饰器;用 class-transformer 做类型转换(@Type()、@Transform());为 Create、Update、Response 操作分别创建 DTO;绝不信任原始用户输入,全部校验。
- 数据库模式(Drizzle ORM):按 NestJS Provider 约定集成 Drizzle ORM;将 Drizzle 客户端包装为可注入 Provider;用 Repository 模式封装数据访问;按领域模块在专用 schema 文件中定义 schema;多步操作使用事务;数据库逻辑不得进入 controller。
- 最佳实践对照:模块——每个领域功能一个模块,不要把一切塞进 AppModule;DI 作用域——默认单例,不要无理由使用 REQUEST;错误处理——自定义异常过滤器加领域错误,不要裸 try/catch 配 console.log;校验——全局 ValidationPipe 加 DTO 装饰器,不要在 controller 中手写 if 检查;数据库——用注入客户端的 Repository 模式,不要在 controller 中直接查询数据库;测试——对 service 做单元测试、对 controller 做 e2e 测试,不要跳过测试或测试实现细节;配置——用 @nestjs/config 加类型化 schema,不要硬编码或直接用 process.env。
- 新领域模块工作流示例:创建模块并正确封装(如 ProductModule 导入 DatabaseModule,声明 controllers、providers,仅导出 ProductService);创建带校验的 DTO(用 @IsString、@MaxLength、@IsNumber、@IsPositive 等装饰器);Service 中做错误处理(注入 ProductRepository,findById 未找到时抛 ProductNotFoundException);验证模块注册(用 grep -r "ProductModule" src/app.module.ts 检查 AppModule 导入,用 npx jest --testPathPattern="product" 运行 e2e 确认导出可用)。
适用边界 · 注意事项
- 不要无理由混用作用域——REQUEST 作用域的 Provider 会级联到所有依赖方
- 绝不要从 controller 直接访问数据库——始终经过 service 和 repository 层
- 避免 forwardRef()——应重构模块消除循环依赖;不要跳过 ValidationPipe,也不要在 API 边界之外才做校验;绝不硬编码密钥,应使用 @nestjs/config 配合环境变量;保持模块聚焦,避免“上帝模块”