Nest.js 核心组件详解文档
一、Controller(控制器)
核心职责
- 请求入口:接收前端发来的 HTTP 请求(GET/POST/PUT/DELETE 等)
- 路由定义:声明接口路径、请求方法、参数来源(Query/Body/Params)
- 请求分发:调用对应的 Service 处理业务逻辑
- 响应处理:接收 Service 处理结果,封装并返回给前端
- 轻量职责:不写复杂业务逻辑,只做 “请求转发 + 响应封装”
典型代码示例
// src/user/user.controller.ts
import { Controller, Get, Post, Body, Param, Query } from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
@Controller('user') // 定义路由前缀:/user
export class UserController {
// 注入 UserService
constructor(private readonly userService: UserService) {}
// GET /user/:id - 根据ID查询用户
@Get(':id')
async getUserById(@Param('id') id: number) {
return this.userService.findById(id);
}
// POST /user - 创建用户
@Post()
async createUser(@Body() createUserDto: CreateUserDto) {
return this.userService.create(createUserDto);
}
}
关键特点
- 用
@Controller()装饰器声明路由前缀 - 用
@Get()@Post()等装饰器声明请求方法和路径 - 依赖注入 Service,实现业务与请求层解耦
二、Service(服务)
核心职责
- 业务逻辑实现:处理核心业务(如用户注册校验、订单计算、数据处理)
- 数据操作:与数据库交互(CRUD)、调用第三方接口、缓存读写
- 可复用性:被多个 Controller 或其他 Service 调用
- 单一职责:一个 Service 只负责一个领域的业务(如 UserService 只处理用户相关逻辑)
典型代码示例
// src/user/user.service.ts
import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
@Injectable() // 标记为可注入的服务
export class UserService {
// 模拟数据库
private users = [{ id: 1, name: 'admin', email: 'admin@example.com' }];
// 根据ID查询用户
async findById(id: number) {
return this.users.find(user => user.id === id);
}
// 创建用户
async create(createUserDto: CreateUserDto) {
const newUser = {
id: this.users.length + 1,
...createUserDto
};
this.users.push(newUser);
return newUser;
}
}
关键特点
- 用
@Injectable()装饰器标记,支持依赖注入 - 可被 Controller、其他 Service、Guard 等注入使用
- 业务逻辑集中,便于单元测试和维护
三、DTO(数据传输对象)
核心职责
- 参数格式定义:声明接口入参的字段、类型、是否必填
- 参数校验:配合
class-validator实现自动参数校验(如邮箱格式、长度限制) - 类型安全:为 TypeScript 提供类型提示,避免参数错误
- 文档作用:明确接口入参规范,前后端沟通更清晰
典型代码示例
// src/user/dto/create-user.dto.ts
import { IsString, IsEmail, IsInt, Min, MaxLength } from 'class-validator';
export class CreateUserDto {
// 用户名:字符串,长度2-20
@IsString()
@MaxLength(20)
name: string;
// 邮箱:必须是合法邮箱格式
@IsEmail()
email: string;
// 年龄:数字,18-100
@IsInt()
@Min(18)
age: number;
}
关键特点
- 配合
class-validator和class-transformer实现自动校验 - 校验失败会自动返回 400 错误,无需手动写校验逻辑
- 仅用于接口数据传输,不包含业务逻辑
四、Guard(守卫)
核心职责
- 权限校验:判断请求是否有权限访问接口(如登录状态、角色权限)
- 前置拦截:在请求到达 Controller 之前执行,不符合条件直接返回 403/401
- 全局 / 局部使用:可全局注册,也可在单个 Controller / 方法上使用
- 灵活控制:支持基于角色、Token、权限的多种校验方式
典型代码示例
// src/common/guards/auth.guard.ts
import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
const token = request.headers.authorization;
// 模拟Token校验
if (!token || !token.startsWith('Bearer ')) {
throw new UnauthorizedException('未登录,请先登录');
}
// 校验通过
return true;
}
}
使用方式
// 在 Controller 上使用(整个控制器的接口都受保护)
@Controller('user')
@UseGuards(AuthGuard)
export class UserController {}
// 在单个方法上使用
@Post()
@UseGuards(AuthGuard)
async createUser(@Body() createUserDto: CreateUserDto) {
return this.userService.create(createUserDto);
}
关键特点
- 实现
CanActivate接口,重写canActivate方法 - 校验失败直接抛出异常,由 Filter 统一处理
- 不依赖业务逻辑,纯权限控制
五、Filter(异常过滤器)
核心职责
- 异常捕获:捕获请求处理过程中抛出的所有异常
- 统一响应格式:将不同类型的异常(如 400/401/403/500)封装成统一的错误响应
- 日志记录:可在过滤器中记录错误日志,便于排查问题
- 避免程序崩溃:防止未捕获的异常导致服务中断
典型代码示例
// src/common/filters/http-exception.filter.ts
import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus } from '@nestjs/common';
import { Request, Response } from 'express';
@Catch() // 捕获所有异常
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
let status = HttpStatus.INTERNAL_SERVER_ERROR;
let message = '服务器内部错误';
// 处理 HttpException 异常
if (exception instanceof HttpException) {
status = exception.getStatus();
const exceptionResponse = exception.getResponse();
message = typeof exceptionResponse === 'string'
? exceptionResponse
: (exceptionResponse as any).message || message;
}
// 统一返回错误格式
response.status(status).json({
code: status,
message,
path: request.url,
timestamp: new Date().toISOString()
});
}
}
注册方式
// src/main.ts 全局注册
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './common/filters/http-exception.filter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new HttpExceptionFilter()); // 全局注册异常过滤器
await app.listen(3000);
}
bootstrap();
关键特点
- 实现
ExceptionFilter接口,重写catch方法 - 支持捕获特定类型异常(如
@Catch(HttpException))或所有异常 - 统一错误响应格式,前端处理更方便
六、Module(模块)
核心职责
- 业务组织:将同一业务领域的 Controller、Service、DTO 等封装为独立模块(如 UserModule、ProductModule)
- 依赖管理:声明模块间的依赖关系(如 UserModule 导入 AuthModule)
- 依赖注入容器:管理模块内所有 Provider(Service、Repository 等)的实例化和生命周期
- 模块化解耦:模块间相互独立,便于团队协作和代码维护
典型代码示例
// src/user/user.module.ts
import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
@Module({
controllers: [UserController], // 声明本模块的控制器
providers: [UserService], // 声明本模块的服务
exports: [UserService] // 导出服务,供其他模块使用
})
export class UserModule {}
根模块 app.module.ts:
// src/app.module.ts
import { Module } from '@nestjs/common';
import { UserModule } from './user/user.module';
import { ProductModule } from './product/product.module';
@Module({
imports: [UserModule, ProductModule], // 导入业务模块
})
export class AppModule {}
关键特点
- 用
@Module()装饰器声明模块配置 controllers:注册本模块的控制器providers:注册本模块的服务 / 提供者imports:导入其他模块exports:导出服务供其他模块使用
七、请求完整流程
八、核心记忆口诀
| 组件 | 核心作用 | 一句话记忆 |
|---|---|---|
| Controller | 接收请求、返回响应 | 接口入口,只管收发 |
| Service | 实现业务逻辑、数据操作 | 业务干活,处理核心 |
| DTO | 参数校验、格式定义 | 校验参数,格式规范 |
| Guard | 权限校验、请求拦截 | 权限看门,校验准入 |
| Filter | 异常捕获、统一错误响应 | 错误兜底,统一返回 |
| Module | 模块组织、依赖管理 | 业务打包,依赖容器 |