关于 nestjs-best-practices
面向 NestJS 开发者的架构与编码实践指南,依据官方文档整理模块边界、依赖注入、异常处理和 DTO 验证等做法。也涵盖 Drizzle ORM 集成及代码审查场景。
主要功能
- 01按领域划分模块
- 02依赖注入作用域选择
- 03统一异常处理模式
- 04DTO 与输入验证
- 05Drizzle ORM 仓储模式
适用场景
- 01设计或重构 NestJS 模块
- 02配置依赖注入与提供者作用域
- 03为 API 添加 DTO 验证
- 04审查异常处理和数据库访问代码
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ giuseppe-trisciuoglio/ developer-kit --skill nestjs-best-practices安装后在 Claude Code 中输入/nestjs-best-practices确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/templates/controller-template.tsmodule-template.tsservice-template.tsreferences/api-validation-dto.mdarch-module-boundaries.mdarchitecture.mddb-drizzle-patterns.mddi-provider-scoping.mderror-exception-filters.md详细介绍
NestJS 最佳实践
概述
本技能基于 NestJS 官方文档,规范模块化架构、依赖注入作用域、异常过滤器、使用 class-validator 验证 DTO,以及 Drizzle ORM 集成模式。
适用场景
- 设计或重构 NestJS 模块或依赖注入
- 创建异常过滤器、验证 DTO 或集成 Drizzle ORM
- 审查代码中的反模式,或熟悉 NestJS 代码库
说明
1. 模块化架构
严格遵循模块封装。每个领域功能都应拥有自己的 @Module():
- 只导出其他模块需要的内容——将内部提供者设为私有
- 仅在不得已时使用
forwardRef()处理循环依赖;优先考虑重构 - 将相关控制器、服务和仓储放在同一模块中
- 使用
SharedModule处理横切关注点(日志记录、配置、缓存)
有关执行规则,请参阅 references/arch-module-boundaries.md。
2. 依赖注入
根据使用场景选择正确的提供者作用域:
| 作用域 | 生命周期 | 使用场景 |
|---|---|---|
DEFAULT | 单例(共享) | 无状态服务、仓储 |
REQUEST | 每个请求创建一个实例 | 请求作用域数据(租户、用户上下文) |
TRANSIENT | 每次注入创建新实例 | 有状态工具、每个使用者各自的缓存 |
- 默认使用
DEFAULT作用域——只有在有充分理由时才使用REQUEST或TRANSIENT - 仅使用构造函数注入——避免属性注入
- 使用
useClass、useValue、useFactory或useExisting注册自定义提供者
有关执行规则,请参阅 references/di-provider-scoping.md。
3. 请求生命周期
理解并遵循 NestJS 请求处理管线:
Middleware → Guards → Interceptors (before) → Pipes → Route Handler → Interceptors (after) → Exception Filters
- 中间件:横切关注点(日志记录、CORS、请求体解析)
- 守卫:授权和身份验证检查(返回
true/false) - 拦截器:转换响应数据、添加缓存、测量耗时
- 管道:验证并转换输入参数
- 异常过滤器:捕获并格式化错误响应
4. 错误处理
在整个应用中统一错误响应:
- 为特定于 HTTP 的错误扩展
HttpException - 创建领域专用异常类(例如,
OrderNotFoundException) - 实现全局
ExceptionFilter,统一格式化错误 - 对预期的业务逻辑失败使用 Result 模式
- 绝不静默吞掉异常
有关执行规则,请参阅 references/error-exception-filters.md。
5. 验证
在 API 边界强制执行输入验证:
- 全局启用
ValidationPipe,并设置transform: true和whitelist: true - 使用
class-validator装饰器标注所有 DTO 属性 - 使用
class-transformer进行类型转换(@Type()、@Transform()) - 为创建、更新和响应操作分别创建 DTO
- 绝不信任原始用户输入——验证所有内容
有关执行规则,请参阅 references/api-validation-dto.md。
6. 数据库模式(Drizzle ORM)
按照 NestJS 提供者规范集成 Drizzle ORM:
- 将 Drizzle 客户端封装在可注入的提供者中
- 使用 Repository 模式封装数据访问
- 在每个领域模块专用的架构文件中定义架构
- 对多步操作使用事务
- 不要将数据库逻辑放在控制器中
有关执行规则,请参阅 references/db-drizzle-patterns.md。
最佳实践
| 领域 | 应该做 | 不要做 |
|---|---|---|
| 模块 | 每个领域功能一个模块 | 把所有内容都塞进 AppModule |
| DI 作用域 | 默认使用单例作用域 | 未经充分理由使用 REQUEST 作用域 |
| 错误处理 | 使用自定义异常过滤器和领域错误 | 使用裸 try/catch 并调用 console.log |
| 验证 | 使用全局 ValidationPipe 和 DTO 装饰器 | 在控制器中手动进行 if 检查 |
| 数据库 | 使用带有注入客户端的仓储模式 | 在控制器中直接查询数据库 |
| 测试 | 对服务进行单元测试,对控制器进行端到端测试 | 跳过测试或测试实现细节 |
| 配置 | 使用带有类型化架构的 @nestjs/config | 硬编码值或使用 process.env |
示例
示例:带验证的新领域模块
构建“Product”功能时,请遵循以下工作流:
1. 创建封装良好的模块:
// product/product.module.ts
@Module({
imports: [DatabaseModule],
controllers: [ProductController],
providers: [ProductService, ProductRepository],
exports: [ProductService], // Only export what others need
})
export class ProductModule {}
2. 创建经过验证的 DTO:
// product/dto/create-product.dto.ts
import { IsString, IsNumber, IsPositive, MaxLength } from 'class-validator';
export class CreateProductDto {
@IsString() @MaxLength(255) readonly name: string;
@IsNumber() @IsPositive() readonly price: number;
}
3. 添加错误处理的服务:
@Injectable()
export class ProductService {
constructor(private readonly productRepository: ProductRepository) {}
async findById(id: string): Promise<Product> {
const product = await this.productRepository.findById(id);
if (!product) throw new ProductNotFoundException(id);
return product;
}
}
4. 验证模块注册:
# Check module is imported in AppModule
grep -r "ProductModule" src/app.module.ts
# Run e2e to confirm exports work
npx jest --testPathPattern="product"
限制和警告
- 没有充分理由时,不要混用作用域 —
REQUEST作用域的提供者会级联影响所有依赖项 - 切勿从控制器直接访问数据库 — 始终通过服务层和仓储层
- 避免使用
forwardRef()— 重构模块以消除循环依赖 - 不要跳过
ValidationPipe— 始终在 API 边界使用 DTO 进行验证 - 切勿硬编码密钥 — 使用带有环境变量的
@nestjs/config - 保持模块聚焦 — 每个模块对应一个领域功能,避免“上帝模块”
参考资料
references/architecture.md— 深入了解 NestJS 架构模式references/— 各项强制规则,附有正确和错误示例assets/templates/— 常见 NestJS 组件的起始模板
评论
支持 Markdown