NestJS 基础
NestJS 是基于 Node.js 的服务端框架,采用 TypeScript、依赖注入 与模块化结构,默认 HTTP 适配器为 Express,可切换 Fastify。见 NestJS 导读、后端入门。
一、框架定位
- 底层 HTTP 引擎:默认使用 Express,可通过配置切换到 Fastify(性能更高)。
- 适用场景:REST API、GraphQL、微服务、WebSocket 应用等。
- 特点:提供一套完整的架构约束,使团队开发更规范、代码更具可维护性;与 TypeScript 深度集成,同时也支持纯 JavaScript。
二、核心设计思想
- 模块化:每个应用由多个模块(Module)组成,模块是代码组织的基本单元。
- 依赖注入:通过 IoC 容器管理对象之间的依赖关系,提升解耦和测试性。
- 装饰器模式:大量使用装饰器(Decorator)来声明路由、依赖、异常处理等,简化元数据定义。
- TypeScript 优先:利用类型系统提升开发体验和代码健壮性,但不强制。
三、核心构件
1. 控制器(Controllers)
- 职责:接收特定请求,返回响应。不包含业务逻辑,只负责路由调度和视图/数据返回。
- 装饰器:
@Controller()定义路径前缀;@Get()、@Post()等定义 HTTP 方法;@Req()、@Res()、@Body()、@Param()等获取请求参数。
ts
import { Controller, Get, Post, Body } from "@nestjs/common";
@Controller("users")
export class UsersController {
@Get()
findAll(): string {
return "This action returns all users";
}
@Post()
create(@Body() createUserDto: CreateUserDto) {
return "User created";
}
}
2. 提供者(Providers)
- 职责:实现业务逻辑、数据访问、工具函数等,可以被注入到其他类中(通常是 Service)。
- 装饰器:
@Injectable()标记一个类可被依赖注入容器管理。
ts
import { Injectable } from "@nestjs/common";
@Injectable()
export class UsersService {
findOne(id: number) {
return { id, name: "John" };
}
}
3. 模块(Modules)
- 职责:将相关的控制器、提供者、其他模块组织在一起。每个应用至少有一个根模块
AppModule。 - 装饰器:
@Module({ imports, controllers, providers, exports })。
ts
import { Module } from "@nestjs/common";
import { UsersController } from "./users.controller";
import { UsersService } from "./users.service";
@Module({
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService], // 允许其他模块导入本模块的提供者
})
export class UsersModule {}
4. 中间件(Middleware)
- 职责:在路由处理器之前执行,常用于日志、请求解析、跨域等。可以基于函数或实现
NestMiddleware接口的类。 - 注册:在模块配置中实现
configure方法或全局注册。
ts
import { Injectable, NestMiddleware } from "@nestjs/common";
import { Request, Response, NextFunction } from "express";
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log("Request...");
next();
}
}
5. 异常过滤器(Exception Filters)
- 职责:捕获应用中的异常,自定义返回格式和状态码。
- 内置过滤器:
HttpException及其子类;可创建自定义异常过滤器。 - 装饰器:
@Catch()指定捕获的异常类型;@UseFilters()绑定到控制器或方法。
ts
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from "@nestjs/common";
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
response.status(exception.getStatus()).json({
statusCode: exception.getStatus(),
message: exception.message,
});
}
}
6. 管道(Pipes)
- 职责:对请求参数进行验证和转换(例如将字符串转为数字,验证 DTO 约束)。
- 常用内置管道:
ValidationPipe(配合 class-validator)、ParseIntPipe等。 - 自定义管道:实现
PipeTransform接口。
ts
import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from "@nestjs/common";
@Injectable()
export class ParseIdPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
const val = parseInt(value, 10);
if (isNaN(val)) throw new BadRequestException("Validation failed");
return val;
}
}
7. 守卫(Guards)
- 职责:决定请求是否被处理,通常用于鉴权和授权。与中间件不同,守卫可以访问执行上下文,知道当前调用的是哪个控制器/方法。
- 装饰器:
@Injectable()实现CanActivate接口;@UseGuards()绑定。
ts
import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common";
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest();
return !!request.headers.authorization;
}
}
8. 拦截器(Interceptors)
- 职责:在请求前/后执行额外逻辑:响应映射、日志、超时处理、缓存等。可以改变返回结果。
- 接口:实现
NestInterceptor的intercept方法。
ts
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from "@nestjs/common";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";
@Injectable()
export class TransformInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(map((data) => ({ data, status: 200 })));
}
}
9. 自定义装饰器(Custom Decorators)
- 职责:封装重复的逻辑,创建可复用的参数装饰器或方法装饰器。
- 工具:
createParamDecorator或普通装饰器工厂。
ts
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const User = createParamDecorator((data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.user;
});
// 在控制器中使用
@Get()
async findOne(@User() user: UserEntity) { ... }
四、CLI 工具 @nestjs/cli
NestJS 提供了强大的命令行工具,显著提升开发效率。
| 命令 | 作用 |
|---|---|
nest new project-name | 创建新项目(内置多种包管理器选择) |
nest generate module <name> | 生成模块文件 |
nest generate controller <name> | 生成控制器文件(自动更新模块) |
nest generate service <name> | 生成服务文件 |
nest generate resource <name> | 生成完整的 REST 或 GraphQL 资源(包括模块、控制器、服务、DTO、实体等) |
nest start | 启动开发服务器(支持热重载) |
nest build | 构建生产代码(输出到 dist 目录) |
nest info | 查看当前环境信息 |
五、总结
| 构件 | 核心作用 | 典型装饰器/接口 |
|---|---|---|
| 控制器 | 路由处理、请求参数获取 | @Controller, @Get, @Post, @Body, @Param |
| 提供者 | 业务逻辑、依赖注入 | @Injectable |
| 模块 | 组织代码结构 | @Module |
| 中间件 | 请求前置拦截 | NestMiddleware |
| 异常过滤器 | 统一错误响应 | @Catch, ExceptionFilter |
| 管道 | 数据验证/转换 | PipeTransform, ValidationPipe |
| 守卫 | 鉴权/授权 | CanActivate, @UseGuards |
| 拦截器 | 请求前后处理、响应映射 | NestInterceptor |
| 自定义装饰器 | 参数/方法装饰器复用 | createParamDecorator |
NestJS 通过这些统一且强有力的抽象,使后端代码结构清晰、易于测试与维护。
参考文献
以下链接在编写时均可正常访问:
| 资料 | 说明 |
|---|---|
| NestJS 文档 | 官方 |
| NestJS 概览 | 第一个应用 |
| Fastify 适配器 | 性能选项 |
相关文章
认证与授权
认证(Authentication):确认「你是谁」(如 JWT、Session)。 - 授权(Authorization):确认「你能做什么」(如 RBAC、策略检查)。
缓存
@nestjs/cache-manager 统一缓存 API,存储实现可插拔。
提供者与服务
Service 是最常见的 Provider,封装业务逻辑。见 module。
守卫 (Guards) 与授权
守卫决定是否放行请求,常用于认证与授权。见 auth。
配置管理(Config 模块)
@nestjs/config 加载 .env 并提供 ConfigService。见 工程化 env。
数据库集成(以 TypeORM 为例)
Nest 通过 @nestjs/typeorm 等包集成 ORM;生产环境用 migration,慎用 synchronize。亦可选用 Prisma、MikroORM 等(见 官方 Database)。