Skip to content

项目架构

总体架构

ACE NestJS Starter 采用模块化、分层的架构设计,遵循 SOLID 原则和领域驱动设计(DDD)的最佳实践。

┌─────────────────────────────────────────────────┐
│                   客户端请求                      │
└─────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│              NestJS 应用层                       │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐      │
│  │  Guards  │  │  Pipes   │  │ Filters  │      │
│  └──────────┘  └──────────┘  └──────────┘      │
└─────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│              业务逻辑层                          │
│  ┌──────────────────────────────────────┐      │
│  │         Controllers                   │      │
│  └──────────────────────────────────────┘      │
│  ┌──────────────────────────────────────┐      │
│  │          Services                     │      │
│  └──────────────────────────────────────┘      │
└─────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│                数据访问层                        │
│  ┌──────────────────────────────────────┐      │
│  │      Prisma ORM / Repositories        │      │
│  └──────────────────────────────────────┘      │
└─────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│               数据存储层                          │
│  ┌────────────┐  ┌────────────┐  ┌──────────┐  │
│  │ PostgreSQL │  │   Redis    │  │   S3     │  │
│  └────────────┘  └────────────┘  └──────────┘  │
└─────────────────────────────────────────────────┘

目录结构

bash
ace-nest-starter/
├── src/                           # 源代码目录
   ├── config/                    # 配置模块
   ├── configuration.ts      # 配置定义
   ├── env.validation.ts     # 环境变量验证(Zod)
   └── index.ts               # 配置导出

   ├── common/                    # 通用功能
   ├── decorators/            # 自定义装饰器
   ├── filters/               # 异常过滤器
   ├── guards/                # 守卫
   ├── interceptors/          # 拦截器
   ├── pipes/                 # 管道
   ├── dto/                   # 通用 DTO
   └── utils/                 # 工具函数

   ├── modules/                   # 业务模块
   ├── auth/                  # 认证模块
   ├── auth.controller.ts
   ├── auth.service.ts
   ├── auth.module.ts
   ├── dto/              # 认证 DTO
   ├── guards/           # 认证守卫
   └── strategies/       # Passport 策略

   ├── users/                 # 用户模块
   ├── users.controller.ts
   ├── users.service.ts
   ├── users.module.ts
   └── dto/              # 用户 DTO

   ├── database/              # 数据库模块
   ├── database.module.ts
   └── prisma.service.ts

   ├── cache/                 # 缓存模块
   ├── cache.module.ts
   └── redis.service.ts

   ├── email/                 # 邮件模块
   ├── upload/                # 文件上传模块
   ├── websocket/             # WebSocket 模块
   ├── scheduler/             # 任务调度模块
   └── oauth/                 # OAuth 模块

   ├── app.module.ts              # 根模块
   ├── app.controller.ts          # 根控制器
   ├── app.service.ts             # 根服务
   └── main.ts                    # 应用入口

├── prisma/                        # Prisma 相关
   ├── schema.prisma              # 数据模型定义
   ├── migrations/                # 数据库迁移
   └── seed.ts                    # 种子数据

├── test/                          # 测试文件
   ├── unit/                      # 单元测试
   ├── e2e/                       # 端到端测试
   └── fixtures/                  # 测试数据

├── docs/                          # 项目文档
├── scripts/                       # 脚本文件
├── docker/                        # Docker 相关

├── .env.example                   # 环境变量示例
├── .eslintrc.js                   # ESLint 配置
├── .prettierrc                    # Prettier 配置
├── nest-cli.json                  # Nest CLI 配置
├── tsconfig.json                  # TypeScript 配置
├── package.json                   # 项目依赖
└── docker-compose.yml             # Docker Compose 配置

核心模块说明

配置模块 (Config Module)

使用 Zod 进行类型安全的配置管理:

typescript
// src/config/configuration.ts
export const configuration = {
  app: registerAs('app', () => ({
    port: env.APP_PORT,
    env: env.NODE_ENV,
    corsOrigins: env.APP_CORS_ORIGINS,
  })),
  database: registerAs('database', () => ({
    url: env.DATABASE_URL,
  })),
  jwt: registerAs('jwt', () => ({
    accessSecret: env.JWT_ACCESS_SECRET,
    refreshSecret: env.JWT_REFRESH_SECRET,
  })),
  // ... 更多配置
};

数据库模块 (Database Module)

使用 Prisma ORM 进行数据库操作:

typescript
// prisma/schema.prisma
model User {
  id        String   @id @default(cuid())
  email     String   @unique
  password  String
  role      Role     @default(USER)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

enum Role {
  USER
  ADMIN
}

认证模块 (Auth Module)

JWT 双令牌认证系统:

  • Access Token: 短期令牌(15分钟)
  • Refresh Token: 长期令牌(7天)
  • 策略: Local + JWT 策略
  • 守卫: JwtAuthGuard, RolesGuard

通用功能 (Common)

异常过滤器

  • AllExceptionsFilter: 全局异常处理
  • HttpExceptionFilter: HTTP 异常处理
  • ValidationExceptionFilter: 验证异常处理

拦截器

  • LoggingInterceptor: 请求日志
  • TransformInterceptor: 响应转换
  • TimeoutInterceptor: 请求超时

管道

  • ZodValidationPipe: Zod 模式验证
  • ParseIntPipe: 整数解析
  • ParseUUIDPipe: UUID 解析

设计模式

1. 依赖注入 (Dependency Injection)

NestJS 的核心特性,实现松耦合:

typescript
@Injectable()
export class UsersService {
  constructor(
    private prisma: PrismaService,
    private cache: CacheService,
  ) {}
}

2. 装饰器模式 (Decorator Pattern)

自定义装饰器简化代码:

typescript
@Public() // 跳过认证
@Roles('admin') // 角色检查
@ApiOperation({ summary: '获取用户列表' })
@Get()
async findAll() {
  // ...
}

3. 策略模式 (Strategy Pattern)

Passport 策略实现多种认证方式:

typescript
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  // JWT 认证策略
}

@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
  // Google OAuth 策略
}

4. 仓储模式 (Repository Pattern)

通过服务层封装数据访问:

typescript
@Injectable()
export class UsersRepository {
  constructor(private prisma: PrismaService) {}

  async findById(id: string) {
    return this.prisma.user.findUnique({ where: { id } });
  }
}

5. 单例模式 (Singleton Pattern)

服务默认为单例:

typescript
@Global()
@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class DatabaseModule {}

数据流

典型的请求处理流程:

  1. 请求到达 → 中间件处理(日志、CORS、压缩等)
  2. 路由匹配 → 找到对应的控制器方法
  3. 守卫验证 → 认证守卫、角色守卫
  4. 拦截器(前) → 日志记录、性能监控
  5. 管道验证 → DTO 验证、数据转换
  6. 控制器处理 → 调用服务层方法
  7. 服务层逻辑 → 业务逻辑处理
  8. 数据访问 → Prisma ORM 操作数据库
  9. 拦截器(后) → 响应转换、日志记录
  10. 异常过滤器 → 错误处理(如果有异常)
  11. 响应返回 → 返回给客户端

模块间通信

同步通信

通过依赖注入直接调用:

typescript
@Injectable()
export class OrdersService {
  constructor(
    private usersService: UsersService,
    private emailService: EmailService,
  ) {}

  async createOrder(userId: string) {
    const user = await this.usersService.findById(userId);
    // ... 创建订单
    await this.emailService.sendOrderConfirmation(user.email);
  }
}

异步通信

使用事件发射器:

typescript
@Injectable()
export class OrdersService {
  constructor(private eventEmitter: EventEmitter2) {}

  async createOrder() {
    // ... 创建订单
    this.eventEmitter.emit('order.created', order);
  }
}

@Injectable()
export class NotificationService {
  @OnEvent('order.created')
  handleOrderCreated(order: Order) {
    // 发送通知
  }
}

最佳实践

1. 关注点分离

  • Controllers: 处理 HTTP 请求,调用服务
  • Services: 包含业务逻辑
  • Repositories: 数据访问逻辑
  • DTOs: 数据传输对象
  • Entities: 数据实体

2. 模块边界

每个模块应该:

  • 高内聚、低耦合
  • 有明确的职责
  • 通过公共接口通信
  • 可独立测试

3. 错误处理

  • 使用自定义异常类
  • 统一错误响应格式
  • 适当的 HTTP 状态码
  • 详细的错误信息(开发环境)

4. 配置管理

  • 环境变量验证
  • 类型安全的配置
  • 敏感信息不提交代码
  • 环境特定的配置

5. 安全最佳实践

  • 输入验证
  • SQL 注入防护(Prisma 自动处理)
  • XSS 防护
  • CSRF 保护
  • 速率限制
  • 安全头(Helmet)

扩展指南

添加新模块

  1. 创建模块文件夹:src/modules/your-module/
  2. 创建模块文件:your-module.module.ts
  3. 创建服务:your-module.service.ts
  4. 创建控制器:your-module.controller.ts
  5. 创建 DTO:dto/create-your-module.dto.ts
  6. app.module.ts 中导入

添加新的配置

  1. .env.example 添加新变量
  2. env.validation.ts 添加 Zod 验证
  3. configuration.ts 添加配置定义
  4. 在服务中注入使用

添加新的数据模型

  1. prisma/schema.prisma 定义模型
  2. 运行 pnpm prisma:generate 生成客户端
  3. 创建迁移:pnpm prisma:migrate
  4. 在服务中使用新模型

Released under the MIT License.