nestjs 架构篇:控制器、服务、数据访问

核心架构分层
控制器层

职责​​:处理 HTTP 请求/响应,参数校验,路由分发

设计原则​​:

  • 仅关注 HTTP 协议交互

  • 无业务逻辑,仅调用服务层

  • 使用装饰器定义路由和参数映射

​代码示例​​:

TypeScript 复制代码
// user.controller.ts
@Controller('users')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Post()
  async create(@Body() createUserDto: CreateUserDto) {
    return this.userService.create(createUserDto);
  }

  @Get(':id')
  findOne(@Param('id', ParseIntPipe) id: number) {
    return this.userService.findOne(id);
  }
}

​关键点​​:

  • @Body()自动解析请求体

  • @Param()提取路由参数

  • 依赖注入 UserService

服务层

职责​​:实现核心业务逻辑,协调数据访问

设计原则​​:

  • 保持无状态(Stateless)

  • 依赖注入数据访问层

  • 使用 DTO 进行数据转换

代码示例​​:

TypeScript 复制代码
// user.service.ts
@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>
  ) {}

  async create(userDto: CreateUserDto): Promise<User> {
    const user = this.userRepository.create(userDto);
    return this.userRepository.save(user);
  }

  async findOne(id: number): Promise<User> {
    return this.userRepository.findOneBy({ id });
  }
}

关键点​​:

  • 使用 TypeORM Repository 进行数据库操作

  • 业务逻辑与数据持久化解耦

数据访问层

职责​​:数据库交互,数据持久化

实现方式​​:

  • ​Repository 模式​​:通过 TypeORM/Prisma 实现

  • ​DAO 模式​​:直接使用数据库驱动

​代码示例​​(TypeORM):

TypeScript 复制代码
// user.entity.ts
@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ unique: true })
  email: string;

  @CreateDateColumn()
  createdAt: Date;
}

// database.module.ts
@Module({
  imports: [TypeOrmModule.forRoot({
    type: 'postgres',
    host: 'localhost',
    port: 5432,
    entities: [User],
    synchronize: true
  })]
})
export class DatabaseModule {}

关键点​​:

  • 实体类定义数据库表结构

  • 模块化配置数据库连接

模块化架构设计
模块定义规范
TypeScript 复制代码
// user.module.ts
@Module({
  imports: [DatabaseModule],
  controllers: [UserController],
  providers: [UserService],
  exports: [UserService] // 暴露给其他模块
})
export class UserModule {}

核心要素​​:

  • imports:依赖的其他模块

  • exports:导出可复用的组件

  • 默认单例作用域

模块间通信
TypeScript 复制代码
// auth.module.ts
@Module({
  imports: [forwardRef(() => UserModule)] // 解决循环依赖
})
export class AuthModule {}

最佳实践​​:

  • 按业务领域划分模块(如用户、订单、支付)

  • 通过 exports控制服务暴露范围

  • 使用 forwardRef()处理循环依赖

依赖注入系统
依赖注入机制
TypeScript 复制代码
// 服务注入示例
@Controller('orders')
export class OrderController {
  constructor(
    private readonly orderService: OrderService,
    @Inject('PAYMENT_SERVICE') private paymentService: PaymentService
  ) {}
}

实现原理​​:

  • @Injectable()标记可注入类

  • 容器自动解析构造函数参数类型

  • 支持类/值/工厂三种提供者类型

高级注入场景
异步配置注入​​:
TypeScript 复制代码
@Module({
  providers: [{
    provide: 'CONFIG_OPTIONS',
    useFactory: async () => loadConfig()
  }]
})
export class ConfigModule {}
循环依赖解决方案​​:
TypeScript 复制代码
@Module({
  imports: [forwardRef(() => BModule)]
})
export class AModule {}

关键点​​:

  • 优先使用构造函数注入

  • 避免属性注入的隐式依赖

异常处理与数据校验
全局异常过滤器
TypeScript 复制代码
// exceptions.filter.ts
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    response
      .status(500)
      .json({ error: 'Internal Server Error' });
  }
}

// main.ts 注册全局过滤器
app.useGlobalFilters(new AllExceptionsFilter());
数据校验管道
TypeScript 复制代码
// user.dto.ts
export class CreateUserDto {
  @IsEmail()
  email: string;

  @MinLength(6)
  password: string;
}

// 控制器中使用
@Post()
async create(@Body() createUserDto: CreateUserDto) {
  // 自动触发校验
}

关键点​​:

  • 结合 class-validator 实现运行时校验

  • 支持自定义校验器

最佳实践总结
分层架构​
  • 严格区分 Controller/Service/Repository 层

  • 服务层保持无状态,数据访问层封装数据库操作

​模块化设计​
  • 按业务领域划分模块

  • 通过 exports控制服务暴露范围

  • 使用动态模块实现配置化

依赖注入​
  • 优先使用构造函数注入

  • 合理使用作用域(Singleton/Request)

数据持久化​
  • 使用 TypeORM/Prisma 实现 Repository 模式

  • 实体类与数据库表结构严格映射

异常处理​
  • 全局异常过滤器统一处理错误

  • 自定义异常类增强错误语义

相关推荐
lizhongxuan6 小时前
Manus: 上下文工程的最佳实践
算法·架构
小酒星小杜6 小时前
在AI时代,技术人应该每天都要花两小时来构建一个自身的构建系统-Input篇
前端·程序员·架构
幻云20106 小时前
Next.js指南:从入门到精通
开发语言·javascript·人工智能·python·架构
直率阿明6 小时前
从L0-L4五层到云-边-端三层:工业控制架构的演进与重构
重构·架构·工业4.0·isa95
信创天地7 小时前
核心系统去 “O” 攻坚:信创数据库迁移的双轨运行与数据一致性保障方案
java·大数据·数据库·金融·架构·政务
李少兄7 小时前
B/S 架构:现代 Web 应用的核心架构模式
前端·架构·b/s
fiveym8 小时前
持续交付与持续部署(CD)深度解析:定义差异、流程架构与交付模式对比
运维·ci/cd·架构
一条咸鱼_SaltyFish9 小时前
Spring Cloud Gateway鉴权空指针惊魂:HandlerMethod为null的深度排查
java·开发语言·人工智能·微服务·云原生·架构
无心水10 小时前
【分布式利器:腾讯TSF】10、TSF故障排查与架构评审实战:Java架构师从救火到防火的生产哲学
java·人工智能·分布式·架构·限流·分布式利器·腾讯tsf
ITFLY818 小时前
架构很简单:系统拆分与组合
架构