mcpField
N
nestjs-best-practices

nestjs-best-practices

github.com/giuseppe-trisciuoglio开发3663.8k 次安装7 周前更新
代码仓库

关于 nestjs-best-practices

面向 NestJS 开发者的架构与编码实践指南,依据官方文档整理模块边界、依赖注入、异常处理和 DTO 验证等做法。也涵盖 Drizzle ORM 集成及代码审查场景。

主要功能

  1. 01按领域划分模块
  2. 02依赖注入作用域选择
  3. 03统一异常处理模式
  4. 04DTO 与输入验证
  5. 05Drizzle ORM 仓储模式

适用场景

  1. 01设计或重构 NestJS 模块
  2. 02配置依赖注入与提供者作用域
  3. 03为 API 添加 DTO 验证
  4. 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.ts
module-template.ts
service-template.ts
references/
api-validation-dto.md
arch-module-boundaries.md
architecture.md
db-drizzle-patterns.md
di-provider-scoping.md
error-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"

限制和警告

  1. 没有充分理由时,不要混用作用域 — REQUEST 作用域的提供者会级联影响所有依赖项
  2. 切勿从控制器直接访问数据库 — 始终通过服务层和仓储层
  3. 避免使用 forwardRef() — 重构模块以消除循环依赖
  4. 不要跳过 ValidationPipe — 始终在 API 边界使用 DTO 进行验证
  5. 切勿硬编码密钥 — 使用带有环境变量的 @nestjs/config
  6. 保持模块聚焦 — 每个模块对应一个领域功能,避免“上帝模块”

参考资料

  • references/architecture.md — 深入了解 NestJS 架构模式
  • references/ — 各项强制规则,附有正确和错误示例
  • assets/templates/ — 常见 NestJS 组件的起始模板

评论

支持 Markdown