可以把 NestJS 理解成:
"给 Node.js 后端项目提供一套类似 Spring Boot 的工程化框架。"
如果你熟悉 Java/Spring Boot,会非常容易理解 NestJS。它本质上是基于 Node.js + TypeScript 构建的后端框架,核心目标不是"让你能写接口",而是让中大型 Node.js 后端项目更容易组织、扩展、测试和维护。
一、NestJS 是什么?






NestJS 官方定位是一个用于构建高效、可扩展的 Node.js 服务端应用的框架。
它建立在 Node.js HTTP 能力之上,可以使用:
- Express
- Fastify
作为底层 HTTP 平台。
但 NestJS 真正有价值的地方,不是帮你封装 app.get()、app.post()。
而是给 Node.js 后端引入了一套完整的工程架构:
text
NestJS Application
│
┌───────────────┼────────────────┐
│ │ │
Controller Service Module
│ │ │
↓ ↓ ↓
HTTP Business Dependency
API Logic Management
│ │ │
└───────────────┼────────────────┘
↓
Repository / DB
这也是它和 Express 最大的区别。
二、为什么需要 NestJS?
先看最原始的 Node.js/Express 项目。
刚开始可能非常简单:
js
app.get('/users', async (req, res) => {
const users = await db.query('select * from users')
res.json(users)
})
项目小的时候完全没问题。
但是项目越来越大:
text
src/
├── user.js
├── order.js
├── product.js
├── payment.js
├── login.js
├── notification.js
├── utils.js
├── db.js
└── index.js
然后你会慢慢遇到几个问题。
1. 项目架构没有统一约束
Express 本身非常自由。
你可以这样:
text
controller
↓
service
↓
repository
也可以直接:
text
controller
↓
database
甚至:
text
controller
↓
controller
↓
utils
↓
database
框架不会管你。
所以:
Express 给你的是能力,而不是架构。
NestJS 则明确规定了一套推荐的组织方式。
三、NestJS 最核心的几个概念
如果你想真正理解 NestJS,我建议重点理解这 5 个东西:
text
Module
Controller
Provider
Dependency Injection
Guard / Pipe / Interceptor / Middleware
其中前三个是最核心的。
四、Controller:负责接收请求
比如:
typescript
@Controller('users')
export class UserController {
@Get()
getUsers() {
return ['Tom', 'Jerry']
}
}
对应:
http
GET /users
Controller 的职责非常明确:
处理 HTTP 请求。
所以不要把大量业务逻辑塞进 Controller。
推荐:
text
HTTP Request
↓
Controller
↓
Service
↓
Database
而不是:
text
HTTP Request
↓
Controller
├── 参数处理
├── 权限判断
├── 业务逻辑
├── SQL
├── 日志
└── 返回数据
五、Service:负责业务逻辑
例如:
typescript
@Injectable()
export class UserService {
async getUser(id: number) {
const user = await this.userRepository.findById(id)
if (!user) {
throw new Error('用户不存在')
}
return user
}
}
Controller:
typescript
@Controller('users')
export class UserController {
constructor(
private readonly userService: UserService
) {}
@Get(':id')
getUser(@Param('id') id: number) {
return this.userService.getUser(id)
}
}
这里出现了 NestJS 非常重要的东西:
Dependency Injection(依赖注入,DI)
六、Dependency Injection:NestJS 的核心
这个东西如果你了解 Spring,就会特别熟悉。
Java:
java
@Service
public class UserService {
}
然后:
java
@RestController
public class UserController {
@Autowired
private UserService userService;
}
NestJS:
typescript
@Injectable()
export class UserService {
}
然后:
typescript
@Controller('users')
export class UserController {
constructor(
private readonly userService: UserService
) {}
}
NestJS 会自动:
text
UserController
│
│ 需要 UserService
↓
NestJS Container
│
↓
创建 UserService
│
↓
注入 UserController
这就是依赖注入。
七、Module:解决大型项目组织问题
假设我们的系统有:
text
用户
订单
商品
支付
消息
NestJS 推荐拆成:
text
AppModule
│
├── UserModule
│
├── OrderModule
│
├── ProductModule
│
├── PaymentModule
│
└── MessageModule
例如:
typescript
@Module({
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
于是一个模块内部:
text
UserModule
│
├── UserController
│ ↓
├── UserService
│ ↓
└── UserRepository
这样业务边界非常清晰。
八、NestJS 真正帮我们解决的是什么?
我认为可以归纳成 6 个问题。
① 解决项目结构混乱
Express:
text
随便组织
NestJS:
text
Module
├── Controller
├── Service
├── Provider
└── Repository
让大型项目具有统一结构。
② 解决依赖管理问题
例如:
text
OrderService
↓
UserService
↓
UserRepository
↓
Database
NestJS DI Container 自动管理这些对象。
你不需要到处:
typescript
new UserService()
new UserRepository()
new Database()
而是:
typescript
constructor(
private userService: UserService
) {}
九、③ 解决横切逻辑问题
这是 NestJS 非常重要的能力。
比如:
text
所有 API
│
├── 登录校验
├── 权限校验
├── 参数校验
├── 日志
├── 异常处理
└── 数据转换
这些东西不应该每个 Controller 都写一遍。
NestJS 提供:
text
Middleware
Guard
Pipe
Interceptor
Exception Filter
可以理解成:
text
Request
│
↓
Middleware
│
↓
Guard
│
↓
Pipe
│
↓
Controller
│
↓
Service
│
↓
Interceptor
│
↓
Response
例如权限:
typescript
@UseGuards(AuthGuard)
@Get('/profile')
getProfile() {
}
这样就不需要每个接口自己判断:
typescript
if (!user) {
...
}
十、④ 解决参数校验问题
例如接口:
http
POST /users
请求:
json
{
"name": "张三",
"age": 18,
"email": "xxx"
}
NestJS 可以配合 DTO:
typescript
export class CreateUserDto {
@IsString()
name: string
@IsInt()
@Min(0)
age: number
@IsEmail()
email: string
}
Controller:
typescript
@Post()
createUser(
@Body() dto: CreateUserDto
) {
return this.userService.create(dto)
}
于是:
text
HTTP Request
↓
DTO
↓
ValidationPipe
↓
Controller
↓
Service
参数校验从业务代码里面被抽离出来。
十一、⑤ 解决大型系统扩展问题
NestJS 不只是用来写 REST API。
它还支持:
text
REST API
GraphQL
WebSocket
Microservices
消息队列
事件驱动
定时任务
例如:
text
NestJS
│
┌───────────────┼───────────────┐
↓ ↓ ↓
REST GraphQL WebSocket
│ │ │
└───────────────┼───────────────┘
↓
Business Layer
│
┌────────┼────────┐
↓ ↓ ↓
MySQL Redis MQ
所以 NestJS 比较适合:
企业级 Node.js 后端。
十二、⑥ 解决测试问题
因为 NestJS 大量使用 DI,所以测试比较容易。
例如:
typescript
UserController
↓
UserService
↓
UserRepository
测试 Controller 的时候,可以把真正的 UserService 换成 Mock。
text
UserController
↓
MockUserService
这样不用真的连接数据库。
这对大型项目非常重要。
十三、NestJS 和 Express 到底是什么关系?
这个问题很重要。
不要理解成:
text
Express vs NestJS
完全是两个竞争层次。
更准确:
text
NestJS
│
┌────────┴────────┐
↓ ↓
Express Fastify
↓ ↓
Node.js Node.js
NestJS 是更高层的应用框架。
Express/Fastify 更偏底层 HTTP Server。
所以:
typescript
NestJS + Express
或者:
typescript
NestJS + Fastify
都可以。
十四、如果你熟悉 Spring Boot,可以这样对照
这个对你理解 NestJS 非常有帮助:
| NestJS | Spring Boot |
|---|---|
@Module() |
配置/模块体系 |
@Controller() |
@RestController |
@Injectable() |
@Service / Bean |
| Constructor Injection | @Autowired |
| Provider | Bean |
| Guard | Interceptor / Filter / Security |
| Pipe | 参数校验/转换 |
| Interceptor | Interceptor |
| Exception Filter | ExceptionHandler |
| Middleware | Filter |
| DTO | DTO |
| TypeORM / Prisma | JPA / MyBatis |
| NestJS DI Container | Spring IoC Container |
所以如果一句话总结:
NestJS ≈ Node.js 世界里的 Spring Boot。
当然两者底层实现不同,但在工程思想上非常接近。
十五、什么时候应该用 NestJS?
我会这样判断:
小项目
例如:
text
一个简单 BFF
一个小工具 API
10 个接口以内
Express/Fastify 可能就够了。
中大型项目
例如:
text
用户系统
订单系统
支付系统
权限系统
消息系统
管理后台 API
推荐 NestJS。
因为这时候最重要的问题已经不是:
"怎么写一个 HTTP 接口?"
而是:
"几十个人一起开发,半年后这个项目还能不能维护?"
这就是 NestJS 的价值。
十六、用一个实际项目理解
假设你要开发一个电商后端:
text
Ecommerce
│
┌───────────────┼──────────────┐
↓ ↓ ↓
User Order Product
│ │ │
UserModule OrderModule ProductModule
│ │ │
Controller Controller Controller
│ │ │
Service Service Service
│ │ │
Repository Repository Repository
│ │ │
└───────────────┼──────────────┘
↓
Database
同时所有请求:
text
Request
↓
Middleware
↓
AuthGuard
↓
ValidationPipe
↓
Controller
↓
Service
↓
Repository
↓
Database
NestJS 的核心价值就是帮你把这套东西标准化、模块化、自动化。
十七、所以 NestJS 到底解决了什么?
我建议你记住这一句话:
Node.js 本身解决的是"能不能写后端",NestJS 解决的是"怎么把 Node.js 后端工程化"。
再进一步:
text
Node.js
↓
提供运行时能力
Express / Fastify
↓
提供 HTTP 能力
NestJS
↓
提供企业级应用架构
DI + Module + Controller + Service
↓
解决代码组织和依赖管理
Guard + Pipe + Interceptor + Filter
↓
解决横切逻辑
DTO + Validation
↓
解决输入数据治理
Testing + CLI + Ecosystem
↓
解决工程效率和可维护性
所以如果你现在是从前端 / Node.js → AI Agent / 后端工程 这个方向学习,我会建议重点掌握 NestJS 的 Module、DI、Provider、Guard、Pipe、Interceptor,而不是先去背 API。
这几个概念掌握以后,你会发现它和你最近在研究的 Skill / Agent / Workflow / Plugin 的架构思想其实也非常相似:模块化 + 依赖注入 + 生命周期 + 中间层拦截 + 编排。
下面我不只讲"注解一一对应",而是从一个完整请求是怎么进入系统、经过 Controller、Service、依赖注入、校验、权限、异常处理,最后访问数据库的角度,把 NestJS 和 Spring Boot 放在一起讲。
先记住一个核心:
NestJS 和 Spring Boot 的很多设计思想高度相似,但不是注解的机械翻译。
NestJS 更像是把 Spring 的 IoC、模块化、AOP/拦截器、参数校验等思想,用 TypeScript/Node.js 重新实现了一遍。
一、先建立整体认知
假设我们开发一个用户查询接口:
http
GET /users/100
Spring Boot:
text
HTTP Request
↓
Controller
↓
Service
↓
Repository
↓
Database
NestJS:
text
HTTP Request
↓
Middleware
↓
Guard
↓
Pipe
↓
Controller
↓
Service
↓
Repository
↓
Database
两者的核心业务结构其实非常接近:
| 职责 | NestJS | Spring Boot |
|---|---|---|
| HTTP 接口 | Controller | Controller |
| 业务逻辑 | Service / Provider | Service |
| 数据访问 | Repository / Provider | Repository / Mapper |
| 依赖注入 | DI | IoC / DI |
| 模块 | Module | Spring Bean + Configuration / Package |
| 参数校验 | Pipe + DTO | Validation + DTO |
| 权限 | Guard | Spring Security |
| 请求拦截 | Interceptor | Interceptor |
| 全局异常 | Exception Filter | @ControllerAdvice |
| 中间件 | Middleware | Filter |
| ORM | TypeORM / Prisma | JPA / MyBatis |
| 配置 | ConfigModule | application.yml |
| 定时任务 | Schedule | @Scheduled |
下面逐个展开。
二、Controller:处理 HTTP 请求
这是最容易理解的一组。
NestJS
typescript
import { Controller, Get, Param } from '@nestjs/common';
@Controller('users')
export class UserController {
@Get(':id')
getUser(@Param('id') id: string) {
return {
id,
name: '张三'
};
}
}
请求:
http
GET /users/100
NestJS 会匹配:
text
@Controller('users')
+
@Get(':id')
↓
GET /users/100
Spring Boot
java
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable String id) {
return new User(id, "张三");
}
}
对应关系:
text
NestJS Spring Boot
@Controller → @RestController
@Get() → @GetMapping
@Post() → @PostMapping
@Put() → @PutMapping
@Delete() → @DeleteMapping
@Param() → @PathVariable
@Query() → @RequestParam
@Body() → @RequestBody
@Headers() → @RequestHeader
例如 NestJS:
typescript
@Get()
findUsers(
@Query('page') page: number,
@Query('size') size: number
) {
}
Spring:
java
@GetMapping
public List<User> findUsers(
@RequestParam Integer page,
@RequestParam Integer size
) {
}
三、Service:业务逻辑
这是后端项目最重要的分层之一。
假设:
text
查询用户
↓
检查用户是否存在
↓
检查用户状态
↓
查询订单
↓
组装返回数据
这些东西不应该全部写在 Controller。
NestJS
typescript
import { Injectable } from '@nestjs/common';
@Injectable()
export class UserService {
async getUser(id: string) {
const user = await this.userRepository.findById(id);
if (!user) {
throw new Error('用户不存在');
}
return user;
}
}
Controller:
typescript
@Controller('users')
export class UserController {
constructor(
private readonly userService: UserService
) {}
@Get(':id')
getUser(@Param('id') id: string) {
return this.userService.getUser(id);
}
}
Spring Boot
java
@Service
public class UserService {
public User getUser(String id) {
User user = userRepository.findById(id);
if (user == null) {
throw new RuntimeException("用户不存在");
}
return user;
}
}
Controller:
java
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}")
public User getUser(@PathVariable String id) {
return userService.getUser(id);
}
}
对应:
text
NestJS Spring Boot
@Injectable() → @Service
UserService → UserService
constructor injection → constructor injection
这里有一个重要区别:
Spring
很多老项目会看到:
java
@Autowired
private UserService userService;
这是字段注入。
现在更推荐:
java
public UserController(UserService userService) {
this.userService = userService;
}
NestJS
天然推荐构造函数注入:
typescript
constructor(
private readonly userService: UserService
) {}
所以这一块 NestJS 和现代 Spring Boot 的思想非常接近。
四、Provider:NestJS 比较特殊的概念
这里非常容易产生误解。
很多资料会简单说:
text
NestJS Provider ≈ Spring Bean
这个理解是对的,但要更精确一点。
NestJS:
typescript
@Injectable()
export class UserService {
}
它是一个 Provider。
但 Provider 不一定是 Service:
typescript
@Injectable()
export class UserService {}
@Injectable()
export class OrderService {}
@Injectable()
export class UserRepository {}
都可以是 Provider。
甚至:
typescript
{
provide: 'DATABASE',
useFactory: () => {
return createDatabase();
}
}
也是 Provider。
所以:
Provider 是 NestJS DI 容器管理的"依赖对象"。
Spring 中对应的概念更接近:
Bean
例如:
java
@Component
public class UserRepository {
}
或者:
java
@Service
public class UserService {
}
或者:
java
@Bean
public DataSource dataSource() {
return ...
}
它们最终都是进入 Spring IoC 容器的 Bean。
五、Module:NestJS 非常重要
这是 NestJS 和 Spring Boot 理解上的一个关键点。
NestJS:
typescript
@Module({
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
可以理解成:
text
UserModule
│
├── UserController
│
└── UserService
然后:
typescript
@Module({
imports: [
UserModule
]
})
export class AppModule {}
形成:
text
AppModule
│
└── UserModule
│
├── UserController
└── UserService
六、Spring Boot 有没有 Module?
这里不能简单说:
text
NestJS @Module() = Spring @Module()
因为 Spring Boot 没有完全等价的 @Module()。
Spring 更依赖:
text
Package
+
@Component
+
@Service
+
@Repository
+
@Configuration
+
@Bean
+
@ComponentScan
例如:
java
@Configuration
public class UserConfig {
@Bean
public UserService userService() {
return new UserService();
}
}
Spring 会把它加入 IoC 容器。
所以:
text
NestJS
@Module()
↓
明确声明模块边界
↓
imports
providers
controllers
exports
而 Spring:
text
@Component
@Service
@Repository
@Configuration
@Bean
↓
IoC Container
↓
通过 ComponentScan / Configuration 发现和组装
七、NestJS Module 最重要的四个属性
这是实际开发必须理解的。
typescript
@Module({
imports: [],
controllers: [],
providers: [],
exports: []
})
分别是:
text
imports
↓
我依赖哪些模块
controllers
↓
我提供哪些 HTTP Controller
providers
↓
我有哪些依赖对象
exports
↓
哪些 Provider 可以被其他 Module 使用
例如:
typescript
@Module({
controllers: [UserController],
providers: [UserService],
exports: [UserService]
})
export class UserModule {}
然后 OrderModule:
typescript
@Module({
imports: [UserModule],
providers: [OrderService]
})
export class OrderModule {}
于是:
text
OrderModule
│
│ imports
↓
UserModule
│
│ exports
↓
UserService
这其实是在解决:
大型项目中的依赖边界问题。
八、DI:依赖注入
这是两套框架最核心的共同思想。
假设:
text
OrderController
↓
OrderService
↓
UserService
↓
UserRepository
如果不用 DI,你可能写:
typescript
const repository = new UserRepository();
const userService = new UserService(repository);
const orderService = new OrderService(userService);
非常麻烦。
NestJS
你只需要:
typescript
constructor(
private readonly userService: UserService
) {}
NestJS 自动完成:
text
NestJS Container
UserController
↑
│ inject
│
UserService
↑
│ inject
│
UserRepository
Spring Boot
同样:
java
public UserController(UserService userService) {
this.userService = userService;
}
Spring IoC Container:
text
Spring Container
UserController
↑
│ inject
│
UserService
↑
│ inject
│
UserRepository
九、为什么 DI 这么重要?
因为它解决了一个非常大的问题:
对象创建和业务使用解耦。
比如:
typescript
class OrderService {
constructor(
private userService: UserService
) {}
}
OrderService 不关心:
text
UserService
到底怎么创建?
有没有依赖?
依赖谁?
生命周期是什么?
是不是单例?
全部交给:
text
DI Container
这就是 IoC:
控制反转。
十、DTO + 参数校验
这个在实际 API 开发中非常常用。
假设:
http
POST /users
请求:
json
{
"name": "张三",
"age": 18,
"email": "test@example.com"
}
NestJS
定义 DTO:
typescript
export class CreateUserDto {
@IsString()
name: string;
@IsInt()
@Min(0)
age: number;
@IsEmail()
email: string;
}
Controller:
typescript
@Post()
createUser(
@Body() dto: CreateUserDto
) {
return this.userService.createUser(dto);
}
开启:
typescript
app.useGlobalPipes(
new ValidationPipe()
);
请求进入:
text
HTTP Request
↓
ValidationPipe
↓
CreateUserDto
↓
Controller
如果:
json
{
"name": 123,
"age": -10
}
直接校验失败。
十一、Spring Boot 的 DTO 校验
Java:
java
public class CreateUserRequest {
@NotBlank
private String name;
@Min(0)
private Integer age;
@Email
private String email;
}
Controller:
java
@PostMapping
public User createUser(
@Valid @RequestBody CreateUserRequest request
) {
return userService.createUser(request);
}
对应关系:
text
NestJS Spring Boot
DTO → DTO
@IsString() → @Pattern / 类型约束
@IsNotEmpty() → @NotEmpty
@IsEmail() → @Email
@Min() → @Min
@Max() → @Max
ValidationPipe → Bean Validation
class-validator → Jakarta Validation
所以:
text
NestJS
DTO
↓
ValidationPipe
↓
Controller
对应:
text
Spring
DTO
↓
@Valid
↓
Controller
十二、Guard:权限控制
NestJS 的 Guard 很重要。
例如:
typescript
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest();
return !!request.user;
}
}
使用:
typescript
@UseGuards(AuthGuard)
@Get('/profile')
getProfile() {
}
请求:
text
Request
↓
AuthGuard
↓
是否登录?
↓
Controller
十三、Spring Boot 对应什么?
Spring Boot 通常使用:
text
Spring Security
例如:
java
@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/admin")
public String admin() {
return "admin";
}
或者:
java
.securityMatcher(...)
所以:
text
NestJS Guard
↓
权限 / 登录 / RBAC
大体对应:
text
Spring Security
↓
认证 / 授权 / RBAC
但是:
Guard 并不等于 Spring Security。
Guard 是 NestJS 的一个扩展点,而 Spring Security 是 Spring 生态中完整的安全框架。
十四、Middleware:中间件
Middleware 更接近 HTTP 请求最外层。
NestJS:
typescript
@Injectable()
export class LoggerMiddleware {
use(req, res, next) {
console.log(req.method, req.url);
next();
}
}
请求:
text
Request
↓
Middleware
↓
Controller
常用于:
text
日志
请求 ID
Cookie
Header
原始请求处理
Spring Boot
传统 Spring:
text
Filter
例如:
java
@Component
public class LogFilter implements Filter {
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain
) {
System.out.println("request");
chain.doFilter(request, response);
}
}
所以:
text
NestJS Middleware
≈
Spring Filter
但不是严格的一一对应。
十五、Interceptor:拦截器
这个概念 NestJS 非常有意思。
例如:
typescript
@Injectable()
export class LoggingInterceptor
implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler) {
console.log('before');
return next.handle().pipe(
tap(() => console.log('after'))
);
}
}
执行:
text
Request
↓
Interceptor
↓
Controller
↓
Service
↓
Interceptor
↓
Response
它可以同时处理:
text
请求前
+
请求后
所以可以做:
text
日志
耗时统计
Response 包装
缓存
数据转换
十六、Spring Boot Interceptor
Spring:
java
@Component
public class LoggingInterceptor
implements HandlerInterceptor {
@Override
public boolean preHandle(...) {
System.out.println("before");
return true;
}
@Override
public void afterCompletion(...) {
System.out.println("after");
}
}
所以:
text
NestJS Interceptor
≈
Spring HandlerInterceptor
两者思想非常接近。
十七、Exception Filter vs @ControllerAdvice
这是另一组非常重要的对应关系。
NestJS:
typescript
@Catch(HttpException)
export class HttpExceptionFilter
implements ExceptionFilter {
catch(exception, host) {
const response = host
.switchToHttp()
.getResponse();
response.status(500).json({
code: 500,
message: '服务器错误'
});
}
}
可以全局注册:
typescript
app.useGlobalFilters(
new HttpExceptionFilter()
);
Spring Boot
通常:
java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handle(Exception e) {
return ResponseEntity
.status(500)
.body(...);
}
}
所以:
text
NestJS ExceptionFilter
↓
全局异常处理
Spring @RestControllerAdvice
↓
全局异常处理
这个对应非常强。
十八、完整请求生命周期对比
现在把前面所有东西串起来。
NestJS
text
HTTP Request
│
↓
Middleware
│
↓
Guard
│
↓
Pipe
│
↓
Interceptor
│
↓
Controller
│
↓
Service
│
↓
Repository
│
↓
Database
│
↓
Interceptor
│
↓
Response
│
↓
Exception Filter
Spring Boot
text
HTTP Request
│
↓
Filter
│
↓
Spring Security
│
↓
Interceptor
│
↓
Controller
│
↓
Service
│
↓
Repository
│
↓
Database
│
↓
Interceptor
│
↓
Response
│
↓
@ControllerAdvice
你会发现:
两者解决的问题高度相似。
十九、ORM:TypeORM / Prisma vs JPA / MyBatis
NestJS 本身并不强制你使用某个 ORM。
常见:
text
NestJS
├── TypeORM
├── Prisma
├── Sequelize
└── Drizzle
例如 TypeORM:
typescript
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
}
Repository:
typescript
@Injectable()
export class UserRepository {
constructor(
@InjectRepository(User)
private repository: Repository<User>
) {}
findById(id: number) {
return this.repository.findOneBy({ id });
}
}
Spring Boot:
java
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
}
Repository:
java
public interface UserRepository
extends JpaRepository<User, Long> {
}
对应:
text
NestJS TypeORM
↓
Entity
↓
Repository
Spring JPA
↓
Entity
↓
Repository
但如果 Spring 使用 MyBatis:
text
Service
↓
Mapper
↓
SQL
这又是另一种数据访问模式。
二十、配置管理
NestJS:
typescript
ConfigModule.forRoot({
isGlobal: true
});
然后:
typescript
constructor(
private configService: ConfigService
) {}
const port =
this.configService.get('PORT');
配置:
text
.env
PORT=3000
DATABASE_URL=xxx
Spring Boot:
yaml
server:
port: 8080
database:
url: xxx
Java:
java
@Value("${server.port}")
private Integer port;
或者更推荐:
java
@ConfigurationProperties(prefix = "database")
所以:
text
NestJS ConfigModule
≈
Spring Boot Configuration
二十一、一个完整 User 模块对照
现在我们写一个真正的 CRUD。
NestJS
text
user/
├── user.module.ts
├── user.controller.ts
├── user.service.ts
├── user.repository.ts
├── user.entity.ts
└── dto/
└── create-user.dto.ts
Module
typescript
@Module({
controllers: [UserController],
providers: [
UserService,
UserRepository
],
exports: [
UserService
]
})
export class UserModule {}
Controller
typescript
@Controller('users')
export class UserController {
constructor(
private userService: UserService
) {}
@Get(':id')
getUser(@Param('id') id: string) {
return this.userService.getUser(id);
}
@Post()
createUser(
@Body() dto: CreateUserDto
) {
return this.userService.createUser(dto);
}
}
Service
typescript
@Injectable()
export class UserService {
constructor(
private userRepository: UserRepository
) {}
getUser(id: string) {
return this.userRepository.findById(id);
}
createUser(dto: CreateUserDto) {
return this.userRepository.create(dto);
}
}
二十二、Spring Boot 对应结构
text
user/
├── UserController.java
├── UserService.java
├── UserRepository.java
├── User.java
└── CreateUserRequest.java
Controller:
java
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(
UserService userService
) {
this.userService = userService;
}
@GetMapping("/{id}")
public User getUser(
@PathVariable String id
) {
return userService.getUser(id);
}
@PostMapping
public User createUser(
@Valid @RequestBody CreateUserRequest request
) {
return userService.createUser(request);
}
}
Service:
java
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(
UserRepository userRepository
) {
this.userRepository = userRepository;
}
public User getUser(String id) {
return userRepository.findById(id);
}
public User createUser(
CreateUserRequest request
) {
return userRepository.save(...);
}
}
你会发现两者几乎是同一种架构思想。
二十三、最重要的不是"注解对应",而是思想对应
我建议你把这张图记下来:
text
NestJS Spring Boot
│ │
│ │
@Module() Configuration
│ │
↓ ↓
DI Container IoC Container
│ │
┌────────┼────────┐ ┌────────┼────────┐
↓ ↓ ↓ ↓ ↓ ↓
Controller Service Repository Controller Service Repository
│ │ │ │ │ │
└────────┼────────┘ └────────┼────────┘
↓ ↓
Database Database
横切能力:
text
NestJS Spring Boot
Middleware → Filter
Guard → Spring Security
Pipe → Validation
Interceptor → HandlerInterceptor
ExceptionFilter → ControllerAdvice
二十四、如果你从前端转 NestJS,最应该先学什么?
结合你本身前端 + Node.js 的背景,我建议不要一上来学一堆 NestJS API。
按照这个顺序:
第一阶段:理解 NestJS 基础架构
text
Module
↓
Controller
↓
Provider / Service
↓
DI
先搞懂:
NestJS 到底是怎么创建和管理对象的。
第二阶段:掌握请求生命周期
text
Middleware
↓
Guard
↓
Pipe
↓
Interceptor
↓
Controller
↓
Service
这部分理解后,你基本就知道 NestJS 为什么这样设计。
第三阶段:数据库
学习:
text
Entity
Repository
Transaction
ORM
Migration
建议选一个:
text
NestJS + Prisma
或者:
text
NestJS + TypeORM
第四阶段:企业级能力
再学习:
text
JWT
RBAC
Redis
MQ
WebSocket
Microservices
Logging
Config
Testing
二十五、最后给你一张"脑图"
如果让我用最少的概念解释两者:
text
后端应用
│
┌───────────┴───────────┐
│ │
NestJS Spring Boot
│ │
↓ ↓
Module IoC
│ │
└───────────┬───────────┘
↓
Dependency
Injection
│
↓
┌───────────┼───────────┐
↓ ↓ ↓
Controller Service Repository
│ │ │
└───────────┼───────────┘
↓
Database
横切能力:
Middleware → Filter
Guard → Spring Security
Pipe → Validation
Interceptor → Interceptor
Exception → ControllerAdvice
最核心的一句话:
Spring Boot 和 NestJS 都是在解决"如何把一个简单的 HTTP Server,发展成一个可维护、可扩展、可测试的企业级后端系统"。
其中 Spring Boot 的核心是 IoC/DI + Spring 容器 + 自动配置 + Spring 生态 ;NestJS 的核心则是 Module + DI/Provider + Controller + 生命周期/请求管道 + TypeScript 工程化。
如果你接下来想真正掌握 NestJS,我建议下一步直接讲一个非常关键的主题:"NestJS 启动时到底发生了什么?main.ts → AppModule → Module → Provider → DI Container → Controller 是怎么一步步把整个应用启动起来的。" 这会把前面这些概念真正串起来。