NestJS 核心概念
概览
NestJS 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的框架。它使用渐进式 JavaScript,完全支持 TypeScript,并结合了 OOP(面向对象编程)、FP(函数式编程)和 FRP(函数响应式编程)的元素。
架构特点
- 基于 Express 或 Fastify
- 模块化架构设计
- 依赖注入系统
- 装饰器驱动开发
- TypeScript 原生支持
核心概念
模块 (Modules)
模块是 NestJS 应用程序的基本构建块,用于组织应用程序结构。
关键特性:
- 使用
@Module()装饰器定义 - 封装相关的控制器和服务
- 支持模块间的导入导出
- 实现代码的模块化和可重用性
基本结构:
typescript
@Module({
imports: [], // 导入其他模块
controllers: [], // 注册控制器
providers: [], // 注册服务提供者
exports: [] // 导出供其他模块使用
})
export class AppModule {}模块类型:
- 功能模块:封装特定业务功能
- 共享模块:可被多个模块导入
- 全局模块:使用
@Global()装饰器 - 动态模块:运行时配置
控制器 (Controllers)
控制器负责处理传入的请求并返回响应给客户端。
关键特性:
- 使用
@Controller()装饰器定义 - 处理 HTTP 请求路由
- 绑定请求方法(GET、POST、PUT、DELETE 等)
- 参数提取和验证
基本示例:
typescript
@Controller('users')
export class UsersController {
@Get()
findAll() {
return 'This returns all users';
}
@Get(':id')
findOne(@Param('id') id: string) {
return `This returns user #${id}`;
}
@Post()
create(@Body() createUserDto: CreateUserDto) {
return 'This creates a new user';
}
}常用装饰器:
@Get(),@Post(),@Put(),@Delete(),@Patch()@Param(),@Query(),@Body(),@Headers()@Req(),@Res()
服务 (Providers/Services)
服务是可注入的类,用于处理业务逻辑和数据访问。
关键特性:
- 使用
@Injectable()装饰器 - 通过依赖注入使用
- 封装业务逻辑
- 可被控制器或其他服务注入
基本示例:
typescript
@Injectable()
export class UsersService {
private users = [];
findAll() {
return this.users;
}
findOne(id: number) {
return this.users.find(user => user.id === id);
}
create(user: any) {
this.users.push(user);
return user;
}
}依赖注入:
typescript
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
}中间件 (Middleware)
中间件是在路由处理程序之前调用的函数,可以访问请求和响应对象。
关键特性:
- 执行任何代码
- 修改请求和响应对象
- 结束请求-响应循环
- 调用下一个中间件
实现方式:
1. 函数式中间件:
typescript
export function logger(req: Request, res: Response, next: NextFunction) {
console.log(`Request...`);
next();
}2. 类中间件:
typescript
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log('Request...');
next();
}
}应用中间件:
typescript
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('users');
}
}守卫 (Guards)
守卫用于确定请求是否应该被路由处理程序处理,主要用于授权。
关键特性:
- 使用
@Injectable()和CanActivate接口 - 在中间件之后、拦截器之前执行
- 返回 boolean 或
Promise<boolean> - 适用于身份验证和授权
基本示例:
typescript
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> {
const request = context.switchToHttp().getRequest();
return this.validateRequest(request);
}
}使用方式:
typescript
@Controller('users')
@UseGuards(AuthGuard)
export class UsersController {}应用级别:
- 全局守卫
- 控制器级守卫
- 路由级守卫
拦截器 (Interceptors)
拦截器可以在方法执行前后添加额外的逻辑,类似于面向切面编程(AOP)。
关键特性:
- 使用
@Injectable()和NestInterceptor接口 - 在方法执行前后绑定额外逻辑
- 转换函数返回的结果
- 扩展基本函数行为
基本示例:
typescript
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
console.log('Before...');
const now = Date.now();
return next.handle().pipe(
tap(() => console.log(`After... ${Date.now() - now}ms`))
);
}
}使用场景:
- 日志记录
- 响应数据转换
- 缓存管理
- 超时处理
- 异常映射
过滤器 (Exception Filters)
异常过滤器用于捕获和处理应用程序中抛出的异常。
关键特性:
- 使用
@Catch()装饰器 - 实现
ExceptionFilter接口 - 统一异常处理
- 自定义错误响应格式
基本示例:
typescript
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const request = ctx.getRequest();
const status = exception.getStatus();
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: exception.message,
});
}
}使用方式:
typescript
@Post()
@UseFilters(HttpExceptionFilter)
create(@Body() createUserDto: CreateUserDto) {}其他核心概念
管道 (Pipes)
管道用于数据转换和验证。
功能:
- 数据转换:将输入数据转换为所需格式
- 数据验证:验证输入数据,无效时抛出异常
内置管道:
ValidationPipeParseIntPipeParseBoolPipeParseArrayPipeParseUUIDPipe
示例:
typescript
@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number) {
return this.usersService.findOne(id);
}装饰器 (Decorators)
NestJS 广泛使用装饰器来定义应用程序的结构和行为。
常用装饰器类别:
- 类装饰器:
@Module(),@Controller(),@Injectable() - 方法装饰器:
@Get(),@Post(),@UseGuards() - 参数装饰器:
@Param(),@Body(),@Query() - 属性装饰器:
@Inject()
依赖注入 (Dependency Injection)
NestJS 内置强大的依赖注入系统。
Provider 作用域:
DEFAULT:单例模式(默认)REQUEST:每个请求创建新实例TRANSIENT:每次注入创建新实例
自定义 Provider:
typescript
{
provide: 'CONFIG',
useValue: { apiKey: 'xxx' }
}请求生命周期
- 接收请求
- 中间件执行
- 守卫执行
- 拦截器(请求前)
- 管道执行
- 路由处理器执行
- 拦截器(响应后)
- 异常过滤器(如有异常)
- 返回响应
最佳实践
- 模块化设计:按功能划分模块
- 单一职责:每个类只负责一个功能
- 依赖注入:充分利用 DI 系统
- 类型安全:使用 TypeScript 和 DTO
- 异常处理:统一使用异常过滤器
- 验证管道:使用 ValidationPipe 和 class-validator
- 配置管理:使用 ConfigModule
- 日志记录:使用内置 Logger 或集成第三方库
学习路径建议
- 从简单的控制器和服务开始
- 理解模块化架构
- 掌握依赖注入机制
- 学习请求生命周期和各组件的执行顺序
- 实践中间件、守卫、拦截器的使用场景
- 深入学习高级特性(微服务、WebSocket、GraphQL 等)
