目录
- 前言
- 一、NestJS 概念
- 二、一个请求在 NestJS 中怎么走(请求流程)(⭐️⭐️⭐️)
- 三、NestJS 运行架构图(简图)
- 四、NestJS 的核心机制(必须记住)(⭐️⭐️⭐️⭐️⭐️)
- 五、NestJS 核心成员全量速览表(建议收藏)
- 六、重点核心成员「逐个突破」
- 1、Module:结构与边界(⭐️⭐️⭐️⭐️⭐️)
- 2、Provider:一切可注入的对象
- (1)、Service(最核心)
- 3、Controller:只做“协议层”
- 4、请求增强类:约束和治理
- (1)、Middleware(请求最外层)
- (2)、Guard(访问控制层)(⭐)
- (3)、Pipe(参数治理层)(⭐)
- (4)、Interceptor(横切增强核心)(⭐)
- (5)、Exception Filter(异常兜底层)(⭐)
- 5、IoC / DI 依赖注入:NestJS 的灵魂(⭐️⭐️⭐️⭐️⭐️)
- (1)、认识 IoC / DI
- (2)、NestJS 中的 IoC / DI
- ①、定义 Provider(能力)
- ②、消费 Provider(不再 new)
- ③、用 Module 把能力“声明”给容器
- 七、传统 MVC vs NestJS:核心差异总览表(重点版)(⭐️)
- 八、标准企业级 NestJS 分层建议(规范版)
- 九、「企业业务」架构图
- 十、NestJS、Fastify 和 Express 全方位对比
- 十一、NestJS 默认使用 Express做了什么工作?
- 十二、如何将 NestJS 的运行时适配器由 Express 替换为 Fastify?(⭐️)
- 1、为什么 NestJS 可以“随便换” Express / Fastify?
- 2、替换为 Fastify(标准做法)
- (1)、安装依赖(必须)
- (2)、修改 main.ts
- 3、Fastify 专属能力(可选但常用)
前言
NestJS = Node.js 世界里的 Spring 框架。
一、NestJS 概念
NestJS 是一个基于 TypeScript 的、强约束、架构优先的 Node.js 服务端框架。
它的核心目标不是“写得快”,而是:
- 写得稳
- 可扩展
- 可维护
- 可测试
- 可演进
NestJS 解决的是 Node.js 的「工程失控」问题:
| 传统 Node / Express 痛点 | NestJS 对应解决方案 |
|---|---|
| 目录结构随意 | Module 强约束 |
| 依赖注入缺失 | 内置 IoC 容器 |
| 中间件混乱 | Middleware / Guard / Interceptor / Pipe 分层 |
| 业务代码和框架代码混在一起 | Controller / Service / Provider |
| 测试困难 | 天然可 Mock、可单测 |
| 大型项目难以协作 | 清晰边界 + 依赖反转 |
NestJS 是把 Java / Spring 的工程思想 引入到了 Node.js 世界。
二、一个请求在 NestJS 中怎么走(请求流程)(⭐️⭐️⭐️)
你会发现:
- Controller 不重要,它只是一个“转发器”
- 真正干活的是 Provider
三、NestJS 运行架构图(简图)
四、NestJS 的核心机制(必须记住)(⭐️⭐️⭐️⭐️⭐️)
如果你只记住了这个,那就记住这个吧。
NestJS 的核心机制包括:
- 模块化架构(Module) → 结构边界,依赖管理
- 依赖注入(IoC / DI Container) → NestJS 的灵魂,管理 Provider 生命周期,解耦、复用、测试友好
- Provider(Service / Repository / Infra 等) → 一切能力的载体,承载业务逻辑、数据访问、基础设施
- 请求拦截体系(Interceptor / Guard / Pipe / Filter) → 请求增强,横切逻辑(企业级必备)
- 生命周期钩子 & 异步机制 → 支撑启动初始化、关闭清理、异步外部资源
五、NestJS 核心成员全量速览表(建议收藏)
| 分类 | 类型 / 名称 | 是否官方 | 重要性 | 作用 | 推荐场景 |
|---|---|---|---|---|---|
| Provider 类 | Service | ❌(约定俗成) | ⭐⭐⭐⭐⭐ | 核心业务逻辑 | 业务处理、状态流转、任务编排 |
| Repository | ❌(架构约定) | ⭐⭐⭐⭐ | 数据访问抽象 | DB 操作、ORM 封装 | |
| Infra | ❌(架构约定) | ⭐⭐⭐⭐ | 外部依赖封装 | MQ / Redis / SDK / OSS | |
| Factory | ✅ | ⭐⭐⭐⭐ | 动态创建 Provider 实例 | Redis / MQ / 多租户 DB / SDK 初始化 | |
| Value | ✅ | ⭐⭐⭐ | 常量 / 配置注入 | feature flag、常量、枚举 | |
| Class | ✅ | ⭐⭐⭐⭐ | 多实现替换 | 支付渠道、多通道消息、存储服务 | |
| Async | ✅ | ⭐⭐⭐⭐ | 异步初始化 Provider | 异步连接、远程配置加载 | |
| Token | ✅ | ⭐⭐⭐⭐ | 抽象解耦 | 多实现注入、接口替换、架构解耦 | |
| Controller 类 | HTTP Controller | ✅ | ⭐⭐⭐⭐⭐ | 接收 REST 请求 | CRUD、业务接口 |
| WebSocket Gateway | ✅ | ⭐⭐⭐ | 实时双向通信 | 聊天系统、实时通知 | |
| Microservice Controller | ✅ | ⭐⭐⭐⭐ | 消息通信 | 分布式任务、事件总线 | |
| RPC Controller | ✅ | ⭐⭐⭐ | 远程调用 | 内部服务 RPC | |
| GraphQL Resolver | ✅ | ⭐⭐⭐ | GraphQL 请求处理 | 查询/变更/订阅 | |
| 请求增强类 | Middleware | ✅ | ⭐⭐⭐ | 请求预处理 | 日志、requestId、简单 auth |
| Guard | ✅ | ⭐⭐⭐⭐ | 权限控制 | 登录校验、RBAC、数据权限 | |
| Pipe | ✅ | ⭐⭐⭐⭐ | 参数校验 / 转换 | DTO 校验、类型转换、脏数据防护 | |
| Interceptor | ✅ | ⭐⭐⭐⭐⭐ | 横切增强 | 日志、性能监控、统一响应、缓存、事务 | |
| Exception Filter | ✅ | ⭐⭐⭐⭐ | 异常捕获 | 全局异常处理、日志、监控上报 | |
| 模块与应用 | Module | ✅ | ⭐⭐⭐⭐⭐ | 架构边界、依赖管理 | 拆分业务模块、管理 Provider |
| App / Application | ✅ | ⭐⭐⭐⭐⭐ | 系统启动与关闭 | 启动模块、全局 Provider 管理 | |
| 核心系统级成员 | IoC Container | ✅ | ⭐⭐⭐⭐⭐ | Provider 依赖管理 | Singleton / Request / Transient 管理 |
| Reflect Metadata | ✅ | ⭐⭐⭐⭐ | 装饰器元数据 | 路由、验证、权限、AOP | |
| Platform Adapter | ✅ | ⭐⭐⭐ | 平台适配 | Express / Fastify / Microservice |
重点关注 5 颗 ⭐ 和 4 颗 ⭐ 的。
下面我们分别研究下这里面的重要成员。
六、重点核心成员「逐个突破」
1、Module:结构与边界(⭐️⭐️⭐️⭐️⭐️)
为什么需要 Module?
- 系统会越来越大,不分模块 = 一团乱麻
作用:
- 声明「这个模块有哪些能力」:支持分层架构(Controller → Service → Repository → Infra)
- 控制依赖可见性:支持模块复用、懒加载
- 定义业务边界:保证系统清晰边界和高可维护性
特性:
- imports:引入其他模块
- providers:声明模块内部 Provider
- controllers:声明 Controller
- exports:输出可被其他模块使用的 Provider
示例:
@Module({imports:[],controllers:[],providers:[],exports:[]})exportclassUserModule{}2、Provider:一切可注入的对象
定义:
- 凡是能被 Nest IoC 注入的对象都是 Provider。
重要性:
- 一切业务 和 基础设施 都写在 Provider 中。
作用:
- 承载业务逻辑
- 数据访问
- 基础设施封装
原则:
- 单一职责
- 精简 Controller → Provider 专注业务
- 可替换、多实现(Token / Class Provider)
Provider 生命周期(三种作用域):
| Scope | 生命周期特点 |
|---|---|
| Singleton | 应用启动实例化 → 全局共享 → 应用关闭销毁 |
| Request | 每次请求生成实例 → 请求结束销毁 |
| Transient | 每次注入生成实例 → 使用完销毁 |
Provider 主要包括以下成员:
- Service
- Repository
- Cache / MQ
- SDK 封装
- 工具类
企业级应用:
- Service 调用 Repository + Infra → 保证 Controller 薄
- Factory / Async Provider → 异步初始化外部资源
- Token / Class Provider → 支持支付渠道、消息通道替换
(1)、Service(最核心)
NestJS 的 Service,是 IoC 容器中的“业务能力单元”,它负责表达业务规则、编排业务流程(业务正确性),而不是处理技术细节。
Service 的本质(非常重要):
| 维度 | 本质 |
|---|---|
| 架构层面 | Application / Domain 层的载体 |
| IoC 角度 | 被容器托管的可注入对象 |
| 职责角度 | 业务规则 + 业务流程编排 |
| 可测试性 | 可 Mock、可独立测试的纯逻辑单元 |
✅ Service 应该做的事:
| 类型 | 举例 |
|---|---|
| 业务规则 | 状态流转、校验 |
| 业务流程 | 下单 → 锁库存 → 支付 → 发通知 |
| 事务控制 | DB 事务 / 分布式事务 |
| 资源协调 | DB + Redis + MQ |
| 业务抽象 | 统一业务接口 |
❌ Service 不应该做的事:
| 禁止 | 原因 |
|---|---|
| 解析 HTTP 请求 | 属于 Controller |
| 操作 Request / Response | 破坏分层 |
| 写 SQL | Repository 的职责 |
| 写 Redis Key 细节 | Infra 关注点 |
| 关心 UI 展示 | Presentation 关注点 |
示例:
@Injectable()exportclassUserService{}3、Controller:只做“协议层”
Controller 是 NestJS 的“传输适配层(Transport Adapter)”,而不是业务层。
Controller 的职责(必须克制):
- 接收请求
- 参数提取
- 返回响应
- ❌ 不写业务逻辑
Controller 的本质(非常重要):
| 维度 | 本质 |
|---|---|
| 架构层 | Presentation Layer(表现层) |
| 职责 | 协议适配 + 请求入口 |
| 复杂度 | 应该极低 |
| 生命周期 | 被 IoC 管理 |
| 可替换性 | 可以被 GraphQL / RPC / MQ 替代 |
Controller 不是核心逻辑所在,而是“可被替换的一层壳”。
与 MVC 架构的 Controller 过于肥大不同,NestJS 刻意对 Controller 做了瘦身:
- 业务逻辑全部下沉到 Service,Controller 只负责“接、转、发(调)”。
- Controller 越薄,系统越健康。
✅ Controller 能干什么(明确边界):
| 职责 | 说明 |
|---|---|
| 路由声明 | @Controller / @Get |
| 协议绑定 | HTTP / GraphQL / RPC |
| 参数获取 | @Body / @Query / @Param |
| DTO 校验 | Pipe + class-validator |
| 调用 Service | 只调用、不实现 |
| 返回结果 | 统一响应结构 |
❌ Controller 禁止做的事(红线):
| 禁止项 | 为什么 |
|---|---|
| 写业务规则 | 破坏分层 |
| 操作数据库 | 严重越权 |
| 写 Redis / MQ | Infra 泄漏 |
| try/catch 业务异常 | 应交给 Filter |
| 拼装复杂对象 | 应在 Service |
Controller 的典型结构(标准范式):
@Controller('orders')exportclassOrderController{constructor(privatereadonlyorderService:OrderService,){}@Post()create(@Body()dto:CreateOrderDto){returnthis.orderService.create(dto);}}Controller 的分类(企业级常见):
- REST Controller(最常见)
- RPC / 微服务 Controller
- GraphQL Resolver(Controller 的另一种形态)
- BFF Controller(前端友好)
好 Controller 的 5 条铁律(设计原则):
- 每个方法 ≤ 5 行
- 只做参数映射
- 不写 if / for
- 只依赖 Service / Facade
- 返回 DTO / ViewModel
4、请求增强类:约束和治理
定义:
- 请求增强类 = 不处理业务本身,而是对“请求/响应生命周期”进行增强、约束、治理的组件。
它们的共同特点是:
- 关心 请求什么时候来、是否允许进入、如何变形、如何返回、如何兜底
- 是 AOP(面向切面编程)思想的具体落地
- ❌ 不关心具体业务
作用:
- 在请求进入 Controller 前、响应返回前进行增强
- 保证 Controller 只处理请求入口,业务逻辑在 Provider
NestJS 的五大请求增强类(官方):
| 类型 | 执行位置 | 核心职责 |
|---|---|---|
| Middleware | 最外层 | 原始请求预处理 |
| Guard | Controller 之前 | 是否允许进入 |
| Pipe | 参数进入 Controller 之前 | 校验 / 转换 |
| Interceptor | Controller 前后 | 横切增强 |
| Exception Filter | 异常抛出后 | 统一异常处理 |
(1)、Middleware(请求最外层)
定位:
- 对原始 Request / Response 做最早处理
特点:
- 基于 Express / Fastify
- 无法使用 DI(或能力有限)
- 更偏“框架级”
典型用途:
- requestId 注入
- 原始日志
- CORS
- 简单鉴权(不推荐复杂)
❌ 不适合:
- 复杂权限
- 业务逻辑
- 依赖 Service 的场景
(2)、Guard(访问控制层)(⭐)
定位:
- 决定“这个请求有没有资格进入 Controller”
特点:
- 返回 boolean / Promise
- 可以使用 DI
- 强语义:是否放行
典型用途:
- 登录校验
- RBAC / ABAC 权限
- 数据级权限(是否能访问某资源)
canActivate(context:ExecutionContext):boolean{constreq=context.switchToHttp().getRequest()return!!req.user}Guard 是权限体系的唯一正解
(3)、Pipe(参数治理层)(⭐)
定位:
- 参数进入 Controller 前的“质量控制器”
特点:
- 在参数级别执行
- 可转换 / 可抛错
- 强配合 DTO + class-validator
典型用途:
- 参数校验
- 类型转换
- 默认值填充
- 防脏数据
@Body(newValidationPipe())create(@Body()dto:CreateUserDto){}Pipe = 参数防火墙
(4)、Interceptor(横切增强核心)(⭐)
定位:
- Controller 前后包裹执行
特点:
- 可拿到返回值
- 可修改响应
- 可做 AOP
典型用途(非常关键):
- 统一响应格式
- 日志 & 性能统计
- 缓存
- 事务控制
- 幂等控制
returnnext.handle().pipe(tap(()=>console.log('after')),)Interceptor 是 NestJS 的灵魂
(5)、Exception Filter(异常兜底层)(⭐)
定位:
- 异常统一收口
特点:
- 捕获 throw 出来的异常
- 可分类处理
- 可上报监控
典型用途:
- HTTP 异常统一格式
- 错误码规范
- Sentry / 日志系统
@Catch(HttpException)exportclassHttpFilter{}Filter = 系统稳定器
5、IoC / DI 依赖注入:NestJS 的灵魂(⭐️⭐️⭐️⭐️⭐️)
(1)、认识 IoC / DI
- IoC(控制反转)是一种新的设计思想——提供了另一种创建对象的方式(不用 new)。
- DI(依赖注入)是 IoC 最主流、最工程化的实现方式(DI = 容器在运行时,把对象所需的依赖“注入”进去)。
IoC 的核心反转点:
| 维度 | 传统方式 | IoC |
|---|---|---|
| 创建对象 | 自己 new | 容器创建 |
| 管理依赖 | 对象自己 | 容器统一管理 |
| 生命周期 | 不可控 | 可配置 |
| 替换实现 | 困难 | 极其容易 |
从“对象控制一切” → “容器控制一切”
常见 DI 方式:
| 方式 | 示例 |
|---|---|
| 构造函数注入 | NestJS / Spring |
| 属性注入 | Angular |
| 方法注入 | 少见 |
NestJS 使用的是 构造函数注入(最安全)。
(2)、NestJS 中的 IoC / DI
不理解 IoC / DI,就永远只是在“用 NestJS 写接口”,而不是“用 NestJS 构建系统”。
- NestJS 的核心能力,本质上是一个“强约束、强治理的 IoC 容器”。
- IoC 是“控制权反转”,
- DI 是“反转的具体实现方式”。
作用:
- 管理 Provider 生命周期(Singleton / Request / Transient)
- 支撑模块间解耦、可替换实现、可 Mock 测试
核心价值:
- 解耦 → Controller / Service / Repository 不直接创建依赖
- 复用 → 同一 Provider 可被多个模块注入
- 测试友好 → Mock / 替换 Provider 容易
「没有 IoC」会发生什么(对照组):
classPaymentService{pay(){return'pay success'}}classOrderService{privatepaymentService=newPaymentService()createOrder(){returnthis.paymentService.pay()}}❌ 问题:
- OrderService 强依赖 PaymentService
- 无法替换实现
- 难测试、难扩展
使用 NestJS IoC 的最小示例(推荐记住):
①、定义 Provider(能力)
@Injectable()exportclassPaymentService{pay(){return'pay success'}}②、消费 Provider(不再 new)
@Injectable()exportclassOrderService{constructor(privatereadonlypaymentService:PaymentService,){}createOrder(){returnthis.paymentService.pay()}}OrderService 不关心 PaymentService 怎么来的
③、用 Module 把能力“声明”给容器
@Module({providers:[PaymentService,OrderService],})exportclassOrderModule{}到这里为止:OrderService 的依赖关系已经“声明完毕”,实例创建权完全交给 Nest
根据上述“①、②、③”整个典例来看,当 Nest 启动时发生了什么?(IoC 真正生效的地方)
- 扫描 OrderModul
- 发现 PaymentService、OrderService
- 解析 OrderService 构造函数参数
- 自动创建 PaymentService
- 注入进 OrderService
‼️OrderService 从来没 new 过任何东西。
七、传统 MVC vs NestJS:核心差异总览表(重点版)(⭐️)
| 维度 | 传统 MVC | NestJS |
|---|---|---|
| 架构中心 | Controller | Module + Provider |
| 设计核心 | 请求 → 响应 | 能力组合 + 依赖注入 |
| 依赖管理 | 手动 new / 引入 | IoC 容器统一管理 |
| 业务组织 | Controller 膨胀 | Service 解耦、可组合 |
| 扩展机制 | Hook / 中间件有限 | Guard / Pipe / Interceptor / Filter |
| 面向对象 | 偏过程式 | 强 OOP + DDD 友好 |
| 测试友好度 | 较弱 | 极强(天然 Mock) |
| 企业级能力 | 中小项目为主 | 天然支持大型系统 |
八、标准企业级 NestJS 分层建议(规范版)
src/├── modules/│ └── business/│ ├── business.controller.ts │ ├── business.service.ts ← 业务 │ ├── business.repository.ts ← 数据 │ ├── clients/│ │ └── aliyun.client.ts ← Infra │ ├── dto/│ └── business.module.ts ├── infra/│ ├── redis/│ ├── logger/│ └── queue/九、「企业业务」架构图
十、NestJS、Fastify 和 Express 全方位对比
| 维度 | Express | Fastify | NestJS |
|---|---|---|---|
| 定位 | 轻量级 HTTP 框架 | 高性能 HTTP 框架 | 企业级应用框架 |
| 抽象层级 | 低(接近原生 HTTP) | 中(HTTP + Schema) | 高(平台级) |
| 是否是应用框架 | ❌ | ❌ | ✅ |
| 默认 HTTP 内核 | 自身 | 自身 | Express(可换 Fastify) |
| 是否可替换 HTTP 内核 | ❌ | ❌ | ✅ |
| 核心设计思想 | Middleware 链 | Plugin + Schema | Module + Provider + IoC |
| 架构中心 | app / router | server / plugin | Module / Provider |
| 依赖注入(DI) | ❌ | ❌ | ✅(核心能力) |
| IoC 容器 | ❌ | ❌ | ✅ |
| 模块化能力 | ❌ | ❌ | ✅ |
| AOP / 拦截体系 | ❌ | ❌ | ✅(Guard / Pipe / Interceptor / Filter) |
| 请求生命周期治理 | 手写 | 部分 | 完整、标准化 |
| Controller 概念 | ❌ | ❌ | ✅ |
| Service 层 | 约定 | 约定 | 一等公民 |
| DTO / 参数校验 | 手写 | Schema 原生支持 | Pipe + class-validator |
| 权限体系 | 手写 | 手写 | Guard(官方模式) |
| 异常处理 | Error Middleware | Error Handler | Exception Filter |
| 统一响应 | 手写 | 手写 | Interceptor |
| 事务 / 幂等 / 缓存 | 手写 | 手写 | Interceptor / Provider |
| 中间件机制 | Middleware | Plugin(更强) | Middleware(最外层) |
| 插件生态 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐(基于 Adapter) |
| 类型支持(TS) | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 性能 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐(取决于底层) |
| 高并发能力 | 一般 | 非常强 | 强(Fastify 模式) |
| 测试友好度 | 一般 | 一般 | 极强(天然 Mock) |
| 微服务支持 | ❌ | ❌ | ✅(官方) |
| GraphQL 支持 | ❌ | ❌ | ✅ |
| WebSocket 支持 | 手动 | 插件 | 官方支持 |
| 学习成本 | 低 | 中 | 高 |
| 代码规范约束 | 极低 | 低 | 高(强约束) |
| 项目规模适配 | 小 | 中 | 中 → 超大 |
| 典型项目 | 简单 API / Demo | 高性能 API | 企业后台 / 中台 / BFF |
| 架构演进成本 | 高 | 中 | 低 |
| 可维护性 | 易失控 | 中等 | 非常强 |
| 是否适合大型团队 | ❌ | ⚠️ | ✅ |
十一、NestJS 默认使用 Express做了什么工作?
在 NestJS 中,Express 只是“HTTP 运行时适配器(Runtime Adapter)”。其他所有“应用级能力”几乎全部由 NestJS 自己接管。
NestJS(应用框架) ↓ Express(HTTP适配器/执行器) ↓ Node.js(运行时)Express 不再是“框架”,而是“运行时引擎”
| 层级 | 负责者 |
|---|---|
| HTTP 协议 | Express |
| 路由注册 | NestJS |
| 请求生命周期 | NestJS |
| 权限 / 校验 | NestJS |
| 业务逻辑 | NestJS |
| 异常治理 | NestJS |
| 响应格式 | NestJS |
90% 的“应用逻辑”已经不在 Express 里了
十二、如何将 NestJS 的运行时适配器由 Express 替换为 Fastify?(⭐️)
既然 Fastify 比 Express 性能更强大,那么如何快速将 NestJS 的运行时适配器由 Express 替换为 Fastify 呢?
NestJS 默认使用 Express 时通过 Platform Adapter 抽象了 Web 层,这就给了你替换的机会:
- 你只需要在 bootstrap 阶段替换 Adapter,就可以无痛切换到 Fastify。
1、为什么 NestJS 可以“随便换” Express / Fastify?
NestJS 的核心不直接依赖 Express,而是依赖 @nestjs/platform-* 适配层:
Nest Core ↓ Platform Adapter(Express/Fastify) ↓HTTPServer这正是 NestJS IoC + 适配器模式 的体现。
2、替换为 Fastify(标准做法)
(1)、安装依赖(必须)
npm install@nestjs/platform-fastify fastify⚠️ 不需要再装 express
(2)、修改 main.ts
import{NestFactory}from'@nestjs/core'import{AppModule}from'./app.module'import{FastifyAdapter,NestFastifyApplication,}from'@nestjs/platform-fastify'asyncfunctionbootstrap(){constapp=awaitNestFactory.create<NestFastifyApplication>(AppModule,newFastifyAdapter(),)awaitapp.listen(3000,'0.0.0.0')}bootstrap()✅ 到这里,Express 已被彻底替换为 Fastify
3、Fastify 专属能力(可选但常用)
- 注册 Fastify 插件
constapp=awaitNestFactory.create(AppModule,newFastifyAdapter(),)app.register(require('@fastify/cors'))注意:Fastify 插件 ≠ Nest Middleware
- 使用 Fastify Request / Reply
import{FastifyRequest,FastifyReply}from'fastify'@Get()get(@Req()req:FastifyRequest,@Res()reply:FastifyReply){reply.send({ok:true})}一旦使用 @Res(),Nest 的响应拦截器将失效(和 Express 一样)