Nest.js各组件理解

一、各组件命名原因与设计目标

组件名命名原因设计目标作用位置
Middleware(中间件)源自 Express,意为“中间层处理者”请求预处理(如日志、跨域、session)请求最外层,最先执行
Guard(守卫)比喻为“守门人”权限控制、访问鉴权Middleware 之后,Controller 之前
Interceptor(拦截器)类比 Spring 中的拦截器请求/响应前后扩展逻辑(如日志、缓存、数据格式化)Guard 之后,Pipe 之前;也可在响应后处理
Pipe(管道)比喻为“数据通道”参数验证与转换(如 DTO 校验、类型转换)Interceptor 之后,Controller 方法之前
Filter(过滤器)类比 Java Servlet 中的过滤器异常捕获与统一响应格式处理整个流程中任何位置抛出的异常都会被捕获
DTO(数据传输对象)经典设计模式名明确接口数据结构与类型,提升可读性与可维护性与 Pipe 配合使用,用于参数校验

二、执行顺序

请求 → Middleware → Guard → Interceptor(before)→ Pipe → Controller → Service → Controller → Interceptor(after)→ Filter(异常时)→ 响应

👉Nest.js请求生命周期

三、各个组件详解

下面把每一个组件都拆开来讲,为什么叫这个名字、设计目标是什么、在请求链里到底扮演什么角色

1. Middleware(中间件)

项目说明
为什么叫中间件字面意思:夹在「HTTP 层」与「业务层」之间的件;Express 先叫响的名字,Nest 拿来直接复用。
设计目标只做「请求级」的通用杂事:CORS、日志、 helmet、session、raw-body 解析等,与业务 0 耦合。
在链上的位置最先跑,甚至还没实例化 Controller;可以 next() 也可以提前结束响应。
典型场景app.use(logger)app.use(cors())

✨一句话:Middleware 是「门卫+保洁」,只认请求,不认路由。

2. Guard(守卫)

项目说明
为什么叫守卫借游戏术语:关卡守门人,过不去就 403/401。
设计目标把「能不能进」与「进去干什么」彻底分开;集中处理鉴权、角色、许可证。
在链上的位置Middleware 之后,Pipe 之前;能拿到反射出来的自定义装饰器(如 @Roles())。
典型场景@UseGuards(JwtAuthGuard, RolesGuard)

✨一句话:Guard 只回答「你行不行」,不回答「你对不对」。


3. Interceptor(拦截器)

项目说明
为什么叫拦截器Spring 借来的名字:可以「拦」住请求/响应,再包一层逻辑。
设计目标AOP 精髓——横向扩展;日志、缓存、数据脱敏、统一封装返回值、RxJS 流变换。
在链上的位置请求方向:Guard → Interceptor → Pipe → Controller;响应方向:Controller → Interceptor → 客户端。
典型场景return {data} 自动包成 {code:0,data,msg:'ok'};ETag 缓存。

✨一句话:Interceptor 是「收发室」,进出都要过它手,可以偷看也可以改装。


4. Pipe(管道)

项目说明
为什么叫管道Unix 管道思想:数据从一个命令流向下一个命令;这里指「参数」被一步步转换/校验。
设计目标把「外部不可信数据」变成「内部可靠数据」;校验、转型、设置默认值。
在链上的位置紧贴着要进 Controller 方法的参数;每个参数可以专属一个 Pipe。
典型场景@Body() createUserDto: CreateUserDto 自动做 class-validator 校验;把字符串 id 转成 ObjectId。

✨一句话:Pipe 是「安检仪」,过不去直接 400,过去了就是干净数据。


5. Filter(异常过滤器)

项目说明
为什么叫过滤器借 Servlet 的 Filter 概念:把异常「过滤」掉,换成友好响应。
设计目标统一错误格式、隐藏敏感堆栈、区分环境、写日志、发告警。
在链上的位置整个链路任何地方抛错,都会被最近的 Filter 捕获;不抛错它就不出现。
典型场景把 MongoError 转换成 409 业务码;把 HttpException 包成 {code,msg} JSON。

✨一句话:Filter 是「救火队」,只负责「烧起来后怎么收场」。


6. DTO(数据传输对象)

项目说明
为什么叫 DTO经典《POEAA》模式名:专为网络传输而生的对象,与数据库实体解耦。
设计目标让接口形状显性化、可复用、可组合;配合 Pipe 做校验;屏蔽内部字段。
在链上的位置本身不是可执行组件,而是 Pipe/Controller 的「靶子」;通过 class-validator 装饰器描述规则。
典型场景CreateCatDtoUpdateCatDto 分开控制必填字段;把密码字段排除在返回层(搭配 Exclude())。

✨一句话:DTO 是「合同」,先签字再开工,防止扯皮。


7. 小结(速记表)

组件关键词一句话记忆
Middleware请求级杂活门卫保洁
Guard鉴权守门员
Interceptor横向扩展收发室
Pipe参数校验/转换安检仪
Filter异常格式化救火队
DTO传输形状合同

这些名字不是拍脑袋起的,而是把现实世界的角色映射到代码世界,让开发者一眼就能猜到它该干什么;再通过 AOP+IoC 把「什么时候干」和「怎么干」解耦,最终达到「业务代码里只有业务」的目的。

参考

updatedupdated2025-09-282025-09-28
加载评论