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 模式

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

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

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

相关推荐
空中海1 小时前
Kubernetes 入门基础与核心架构
贪心算法·架构·kubernetes
米高梅狮子3 小时前
08.CronJob和Service
云原生·容器·架构·kubernetes·自动化
SamDeepThinking4 小时前
中小团队需要一个资源微服务
后端·微服务·架构
两万五千个小时4 小时前
为什么你的 Agent 读了文件,却好像什么都没读到?
人工智能·程序员·架构
非优秀程序员5 小时前
智能体的构成--深入探讨Anthropic、OpenAI、Perplexity和LangChain究竟在构建什么。
人工智能·架构·开源
码点滴5 小时前
从“失忆症“到“数智分身“:Hermes Agent 如何重塑你的 AI 交互体验?
人工智能·架构·prompt·ai编程·hermes
狗哥哥5 小时前
面包屑自动推导的算法设计:从“最短路径匹配”到工程可落地
算法·架构
CinzWS6 小时前
A53性能验证:从微架构到系统级——芯片性能的“全息检测“
架构·芯片验证·原型验证·a53
不才小强6 小时前
gRPC实战指南:高性能微服务通信框架
微服务·云原生·架构
zandy10116 小时前
HENGSHI SENSE 6.2 架构全景解析:Data Agent、指标引擎与Headless语义层的工程实现
大数据·人工智能·架构