以下是 NestJS 核心组件的功能解析及区别对比,按请求处理顺序排列(从接收到响应):
1. 模块(Module)
作用:代码组织单元,将控制器、服务等封装为独立功能块(如
UserModule
)核心配置:
@Module({ imports: [其他模块], // 依赖模块 controllers: [控制器], // 注册路由 providers: [服务], // 注册可注入对象 exports: [共享服务] // 暴露给其他模块 })
区别:唯一不参与请求处理的组件,仅用于架构组织
2. 中间件(Middleware)
作用:在路由前/后执行通用逻辑(如日志、CORS)
典型场景:
use(req, res, next) { console.log("请求进入"); next(); // 必须调用!否则阻塞请求 console.log("响应返回"); }
区别:最早执行,可访问原生
req/res
对象
3. 守卫(Guard)
作用:权限验证(如 JWT 鉴权、角色检查)78
典型代码:
@Injectable() export class AuthGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { return validateRequest(request); // 返回 true/false } }
区别:决定请求是否允许进入控制器
4. 拦截器(Interceptor)
作用:在方法执行前后插入逻辑(如日志、响应格式化)
典型场景:
intercept(context, next): Observable { console.log("请求前"); return next.handle().pipe(tap(() => console.log("响应后"))); }
区别:可修改请求/响应数据流,支持异步操作18
5. 管道(Pipe)
作用:数据转换或验证(如类型转换、DTO 校验)
内置管道:
ParseIntPipe
(转换数字)ValidationPipe
(基于 class-validator 校验)
区别:专注处理输入参数,失败抛异常
6. 控制器(Controller)
作用:路由入口,定义 HTTP 端点(如
@Get('/users')
)示例:
@Controller('users') export class UserController { @Get() getAll() { return this.service.findUsers(); } }
区别:唯一直接处理路由的组件
7. 提供器(Provider)
作用:封装业务逻辑(如数据库操作),通过依赖注入复用
类型:服务(
@Injectable
)、仓库、工厂等区别:控制器调用的实际业务执行者
8. 异常过滤器(Exception Filter)
作用:全局捕获未处理异常,定制错误响应
典型场景:
catch(exception, host) { const response = host.switchToHttp().getResponse(); response.status(500).json({ error: "自定义错误" }); }
区别:最后防线,处理管道/控制器抛出的异常
9. 自定义装饰器(Custom Decorator)
作用:扩展元数据(如获取用户 IP、自定义参数)
示例:
export const User = createParamDecorator((data, ctx) => { const request = ctx.switchToHttp().getRequest(); return request.user; // 自动注入用户对象 });
区别:不直接参与流程,用于增强其他组件
关键区别总结
💡 黄金口诀:
模块是集装箱,组织所有组件
中间件是安检门,守卫是门禁卡
管道是质检员,拦截器是包装工
控制器是调度员,提供器是干活工人
异常过滤器是消防员,装饰器是便利贴