NestJS:基于 Node.js 的企业级后端开发框架

介绍

NestJS(简称 Nest)是一套基于 Node.js 的企业级后端开发框架,2017 年由 Kamil Myśliwiec 开源,核心基于 TypeScript,融合:

  • OOP(面向对象编程)
  • FP(函数式编程)
  • AOP(面向切面编程)

底层封装了 Express(默认)/ Fastify 两种 HTTP 引擎,兼顾 Node.js 高性能与 Java SpringBoot 式规范分层架构,专门解决原生 Node.js 开发大型项目结构混乱、依赖管理难、模块化弱的痛点。

一句话理解(适合Java开发工程师)

NestJS相当于 Spring Boot,是上层开发框架,底层可以像 Spring Boot 更换Servlet容器那样,更换HTTP引擎

定位

  • 适用:中大型后端服务、微服务、API 网关、定时任务、WebSocket、RPC 服务
  • 对标前端:Angular(语法、装饰器、模块化思路高度同源)
  • 对标后端:Spring Boot(分层、依赖注入、中间件、拦截器、过滤器完整体系)
  • 优势:强类型、规范约束、开箱即用架构、官方全套生态

特性总览

  1. 原生 TypeScript 优先,完整类型推导
  2. 依赖注入(DI)容器,解耦业务代码
  3. 模块化分层架构(Module / Controller / Service)
  4. 完整切面体系:中间件、拦截器、管道、过滤器、守卫
  5. 多协议支持:HTTP、WebSocket、TCP RPC、gRPC、MQTT
  6. 微服务内置方案,支持集群、消息队列通信
  7. 内置 Swagger 自动接口文档
  8. 统一异常处理、请求校验、响应格式化
  9. 灵活适配器:Express / Fastify 自由切换

架构五层核心概念(由外到内)

1. Module 模块(组织单元)

Nest 一切代码都必须归属于模块,模块是代码划分最小单元,类似 Spring 的包。

模块组成(@Module() 装饰器)

@Module({
  imports: [], // 导入其他模块(共享服务)
  controllers: [], // 当前模块控制器
  providers: [], // 服务、工具、拦截器等注入类
  exports: [], // 对外暴露的 Provider,供其他模块导入使用
})
  • 根模块 AppModule:项目入口,所有模块最终导入到根模块
  • 功能模块:UserModule、OrderModule、GoodsModule 按业务拆分
  • 共享模块 SharedModule:存放通用工具、全局过滤器、公共管道,全局一次导入到处使用

2. Controller 控制器(接收请求层)

负责接收 HTTP 请求、路由分发、参数接收,只做转发,不写业务逻辑。
装饰器:@Controller('user') 定义路由前缀
路由装饰器:@Get() / @Post() / @Put() / @Delete() / @Patch()

示例:

@Controller('user')
export class UserController {
  constructor(private readonly userService: UserService) {} // 依赖注入Service

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.userService.getById(+id); // 调用业务层
  }
}

3. Provider 提供者(业务逻辑层,核心是 Service)

所有可被依赖注入的类都叫 Provider,最常用为 @Injectable() 服务。

  • Service:纯业务逻辑、数据库操作、第三方接口调用
  • 原则:控制器轻量化,所有计算、查询、事务全放 Service
    @Injectable()
    export class UserService {
    async getById(id: number) {
      return { id, name: "张三" };
    }
    }
    
    其他 Provider:拦截器、管道、守卫、自定义工具类

4. 分层完整执行流程(HTTP 请求生命周期)

客户端请求
↓
全局中间件 → 模块中间件
↓
守卫(Guard)鉴权/权限校验
↓
拦截器(Interceptor)前置处理
↓
管道(Pipe)参数转换、数据校验
↓
Controller 路由方法执行
↓
Service 业务逻辑
↓
拦截器后置处理(统一包装返回体)
↓
异常过滤器(ExceptionFilter)捕获所有错误统一格式化
↓ 响应客户端

5. 五大切面组件(AOP)

(1)Middleware 中间件

基于 Express/Fastify 原生中间件,在路由匹配之前执行:日志打印、跨域、cookie 解析
两种写法:函数中间件、Nest 类中间件

(2)Guard 守卫

路由匹配后、进入控制器前执行,权限控制、登录校验(Token 解析、角色判断)
返回 boolean,false 直接 403 拒绝访问,常用 JWT 鉴权守卫

(3)Pipe 管道

作用:参数校验 + 类型转换
内置:ValidationPipe(配合 class-validator 做 DTO 校验)、ParseIntPipe、ParseBoolPipe
DTO(数据传输对象):定义接口入参格式、校验规则

示例 DTO 校验:

import { IsString, IsInt } from 'class-validator';
export class CreateUserDto {
  @IsString()
  name: string;
  @IsInt()
  age: number;
}

(4)Interceptor 拦截器

进入 Controller 前后都可拦截:

  • 前置:修改请求数据
  • 后置:统一封装返回格式({code, data, msg})、超时处理、缓存、日志埋点

(5)ExceptionFilter 异常过滤器

全局捕获所有报错:内置 HttpException、自定义业务异常,统一输出标准化错误响应,区分 4xx/5xx

依赖注入 DI(Nest 核心灵魂)

1. 什么是 DI

容器自动实例化类并自动注入依赖,不用手动 new,实现低耦合、易单元测试。

2. 注入规则

  1. 类加 @Injectable() 才能被容器管理
  2. 构造函数声明依赖,容器自动传入实例
  3. 作用域三种:
    • DEFAULT(单例,全局唯一,默认)
    • REQUEST(每次请求新建实例)
    • TRANSIENT(每次注入新建实例)

3. 自定义注入令牌

处理多实例、第三方库注入:@Inject('TOKEN')

项目目录标准结构(企业规范)

src
├── main.ts                 # 程序入口,创建 Nest 应用实例
├── app.module.ts           # 根模块
├── common                  # 公共通用层
│   ├── decorators          # 自定义装饰器
│   ├── filters             # 全局异常过滤器
│   ├── guards              # 鉴权守卫
│   ├── interceptors        # 全局响应拦截器
│   ├── pipes               # 全局校验管道
│   └── middlewares         # 全局中间件
├── config                  # 配置文件(环境变量、数据库配置)
├── modules                 # 业务模块(按业务划分)
│   ├── user                # 用户模块
│   │   ├── dto             # 入参校验DTO
│   │   ├── user.controller.ts
│   │   ├── user.service.ts
│   │   └── user.module.ts
│   └── order               # 订单模块
├── database                # 数据库实体、ORM 配置(TypeORM / Prisma)
└── utils                   # 工具函数、常量、枚举

官方核心生态库

1. ORM 数据库

  • @nestjs/typeorm:TypeORM,关系型数据库(MySQL、PostgreSQL、SQLite)
  • @nestjs/mongoose:MongoDB ODM
  • Prisma:第三方主流,官方适配良好

2. 文档 & 校验

  • class-validator + class-transformer:DTO 参数校验
  • @nestjs/swagger:自动生成 OpenAPI 接口文档

3. 认证授权

  • @nestjs/jwt:JWT 登录鉴权
  • @nestjs/passport:多登录策略(账号密码、OAuth、第三方登录)

4. 微服务 & 消息队列

  • @nestjs/microservices:微服务核心包,TCP/gRPC/Redis/MQ/Kafka
  • @nestjs/bull:Redis 定时任务、消息队列

5. 缓存 & 配置

  • @nestjs/config:环境变量 .env 统一配置
  • @nestjs/cache-manager:内存/Redis 缓存

6. WebSocket

微服务能力(Nest 强项)

  1. 多传输协议
    • TCP(默认)、gRPC、Redis、RabbitMQ、Kafka、MQTT
  2. 服务拆分:网关 Gateway(HTTP 对外) + 多个微服务(纯业务)
  3. 内置客户端/服务端通信,负载均衡、消息序列化
  4. 事件驱动架构:基于消息队列实现异步解耦

优势与劣势

优点

  1. 强 TS 类型,大型项目维护成本极低
  2. 标准化强制分层,团队代码风格统一
  3. 完整 AOP 体系,鉴权、校验、异常统一处理,减少重复代码
  4. 微服务原生支持,从单体平滑拆分微服务
  5. CLI 脚手架,代码生成提升开发效率
  6. 丰富官方生态,数据库、鉴权、队列开箱即用
  7. 可切换 Fastify,性能远超原生 Express

缺点

  1. 学习曲线比 Express/Koa 陡峭,需要理解 DI、装饰器、模块化
  2. 小型简单接口项目存在过度设计,代码量更多
  3. TS 编译打包相比原生 JS 多一层构建流程
  4. 装饰器语法为 TS 特有,纯 JS 开发体验较差

适用场景 & 不适用场景

适合

  • 企业后台管理接口
  • 多模块复杂后端服务
  • 需要权限、统一校验、标准化返回的项目
  • 分布式微服务系统
  • 长周期迭代、多人协作大型项目

不适合

  • 超简单轻量爬虫、临时脚本
  • 极小单一接口服务(Express/Koa 更轻便)
  • 完全不熟悉 TypeScript 的快速原型开发

和 Express / Koa / SpringBoot 对比简表

框架 语言 架构 依赖注入 微服务 标准化程度
NestJS TS/JS 分层模块化 原生支持 内置 极高
Express JS 中间件平铺 无,手动封装 无原生 极低
Koa2 JS 洋葱中间件 无 无原生 低
SpringBoot Java MVC分层DI 核心 SpringCloud生态 极高

通常使用 Fastify 作为 HTTP 引擎

  • Express:同步中间件模型,路由匹配、请求吞吐量弱,高并发下延迟高
  • Fastify:底层基于 libuv 优化,原生异步、流式解析请求/响应,内置序列化校验,QPS 是 Express 的 2–5 倍,内存占用更低
  • Nest 做了完整适配器封装,切换框架仅需改一行代码,业务代码完全不用改动

Fastify 独有优势

  1. 内置高效 schema 校验(搭配 Nest ValidationPipe 双重校验)
  2. 原生支持 HTTP2、HTTPS、流式上传下载
  3. 更小开销的路由树,百万级路由无性能衰减
  4. 内置请求日志、超时控制、防崩溃机制
  5. 插件生态轻量化,替代 express 各类中间件

兼容性

Nest 所有能力(控制器、DI、守卫、拦截器、微服务、WebSocket、Swagger)对 Fastify/Express 完全兼容,仅部分底层中间件写法有细微差异。


原文出处:/show_1GW3YzPNBc8y.html