☰
NestJS 深入浅出
2026/10/18 16:21:41 网站建设 项目流程

目录

  • 前言
  • 一、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破坏分层
写 SQLRepository 的职责
写 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 / MQInfra 泄漏
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最外层原始请求预处理
GuardController 之前是否允许进入
Pipe参数进入 Controller 之前校验 / 转换
InterceptorController 前后横切增强
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:核心差异总览表(重点版)(⭐️)

维度传统 MVCNestJS
架构中心ControllerModule + 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 全方位对比

维度ExpressFastifyNestJS
定位轻量级 HTTP 框架高性能 HTTP 框架企业级应用框架
抽象层级低(接近原生 HTTP)中(HTTP + Schema)高(平台级)
是否是应用框架❌❌✅
默认 HTTP 内核自身自身Express(可换 Fastify)
是否可替换 HTTP 内核❌❌✅
核心设计思想Middleware 链Plugin + SchemaModule + Provider + IoC
架构中心app / routerserver / pluginModule / Provider
依赖注入(DI)❌❌✅(核心能力)
IoC 容器❌❌✅
模块化能力❌❌✅
AOP / 拦截体系❌❌✅(Guard / Pipe / Interceptor / Filter)
请求生命周期治理手写部分完整、标准化
Controller 概念❌❌✅
Service 层约定约定一等公民
DTO / 参数校验手写Schema 原生支持Pipe + class-validator
权限体系手写手写Guard(官方模式)
异常处理Error MiddlewareError HandlerException Filter
统一响应手写手写Interceptor
事务 / 幂等 / 缓存手写手写Interceptor / Provider
中间件机制MiddlewarePlugin(更强)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 专属能力(可选但常用)

  1. 注册 Fastify 插件
constapp=awaitNestFactory.create(AppModule,newFastifyAdapter(),)app.register(require('@fastify/cors'))

注意:Fastify 插件 ≠ Nest Middleware

  1. 使用 Fastify Request / Reply
import{FastifyRequest,FastifyReply}from'fastify'@Get()get(@Req()req:FastifyRequest,@Res()reply:FastifyReply){reply.send({ok:true})}

一旦使用 @Res(),Nest 的响应拦截器将失效(和 Express 一样)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询