官网:nestjs.com/
中文文档:www.nestjs.com.cn/
NestJS 是基于 Node.js 和 TypeScript 的渐进式后端框架,它的核心设计理念是借鉴了 Angular 的模块化思想,解决了 Express/Koa 等框架过于灵活导致的代码结构混乱问题。
安装 NestJS CLI
npm i -g @nestjs/cli
或者
pnpm i -g @nestjs/cli
验证
nest --version
创建项目
进入到本地存放项目的目录,执行(例如项目名称 demo-project)
nest new demo-project
选择包管理器,我是用的是 pnpm
创建成功
目录解析
carrierxia-admin-server/
├── node_modules/ # 项目依赖包(npm/pnpm 安装后自动生成)
├── src/ # 源代码目录
│ ├── main.ts # 应用入口文件,启动 NestJS 应用
│ ├── app.module.ts # 根模块,定义应用结构
│ ├── app.controller.ts # 根控制器,处理 HTTP 请求
│ ├── app.service.ts # 根服务,业务逻辑层
│ └── app.controller.spec.ts # 控制器单元测试文件
├── test/ # 测试目录
│ ├── app.e2e-spec.ts # 端到端测试文件
│ └── jest-e2e.json # E2E 测试配置文件
├── dist/ # TypeScript 编译输出目录(构建后生成)
├── coverage/ # 测试覆盖率报告目录(运行测试后生成)
├── .gitignore # Git 忽略文件配置
├── eslint.config.mjs # ESLint 代码检查配置
├── nest-cli.json # NestJS CLI 配置文件
├── package.json # 项目配置和依赖管理
├── pnpm-lock.yaml # pnpm 依赖锁定文件
├── README.md # 项目说明文档
├── tsconfig.build.json # TypeScript 构建配置
└── tsconfig.json # TypeScript 编译配置
启动项目
pnpm run start:dev
测试接口
在浏览器输入:http://localhost:3000/ 查看到 Hello World!
或者在终端使用 curl 命令
核心功能
模块化架构(Modular Architecture)
这是 NestJS 最核心的设计理念,强制你按模块组织代码,让项目结构清晰、可维护。应用的最小组织单元是 Module,每个模块封装一组相关的控制器、服务、提供者等。
作用:避免代码混乱,实现功能解耦,结构清晰,便于团队协作和后期维护。
// user.module.ts
import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
@Module({
controllers: [UserController], // 注册控制器
providers: [UserService], // 注册服务/提供者
exports: [UserService] // 导出供其他模块使用
})
export class UserModule {}
依赖注入(Dependency Injection, DI)
NestJS 内置了完整的依赖注入系统,这是实现代码解耦和可测试性的核心。不需要手动创建类的实例,框架会自动管理依赖的创建和注入,降低组件间的耦合度。
作用:代码更加解耦,更方便测试。
// user.service.ts
import { Injectable } from '@nestjs/common';
@Injectable() // 标记为可注入的提供者
export class UserService {
findAll() {
return [{ id: 1, name: '张三' }];
}
}
// user.controller.ts
import { Controller, Get } from '@nestjs/common';
import { UserService } from './user.service';
@Controller('users')
export class UserController {
// 自动注入 UserService 实例
constructor(private readonly userService: UserService) {}
@Get()
findAll() {
return this.userService.findAll(); // 调用服务方法
}
}
控制器与路由(Controllers & Routing)
NestJS 提供了声明式的路由方式,替代了 Express/Koa 手动编写路由的方式。通过装饰器(@Controller、@Get、@Post、@Param 等)定义路由规则,自动解析请求参数。
作用:路由规则清晰直观,参数解析自动化,减少重复代码。
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
@Controller('users') // 基础路由:/users
export class UserController {
@Get() // GET /users
findAll() {
return '所有用户列表';
}
@Get(':id') // GET /users/1
findOne(@Param('id') id: string) {
return `获取 ID 为 ${id} 的用户`;
}
@Post() // POST /users
create(@Body() createUserDto: any) {
return `创建用户:${JSON.stringify(createUserDto)}`;
}
}
中间件(Middleware)
兼容 Express/Koa 中间件,同时提供 Nest 风格的中间件实现方式。在请求到达控制器之前执行,可用于日志记录、身份验证、请求解析等。
作用:处理请求和响应
// logger.middleware.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(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
next(); // 传递给下一个中间件/控制器
}
}
// 在模块中注册
import { Module, MiddlewareConsumer } from '@nestjs/common';
@Module({})
export class AppModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('users'); // 只为 /users 路由应用中间件
}
}
拦截器(Interceptors)
用于在请求处理前后执行逻辑,比如统一响应格式、异常处理、数据转换、缓存等。可以拦截请求和响应,修改返回结果,或捕获控制器方法的执行过程。
作用:在请求前后处理数据
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 => ({
code: 200,
message: 'success',
data: data
}))
);
}
}
// 全局注册(main.ts)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { TransformInterceptor } from './transform.interceptor';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new TransformInterceptor()); // 全局应用
await app.listen(3000);
}
bootstrap();
过滤器(Filters)
专门用于处理异常,替代 try/catch,实现全局或局部的异常统一处理。捕获控制器 / 服务中抛出的异常,返回标准化的错误响应。
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException) // 捕获 HttpException 及其子类
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: exception.getResponse(),
});
}
}
// 全局注册(main.ts)
app.useGlobalFilters(new HttpExceptionFilter());
管道(Pipes)
用于数据验证和转换,比如校验请求参数格式、类型转换等。Nest 内置了多种管道(如 ValidationPipe、ParseIntPipe),也可自定义。
import { Controller, Get, Param, ParseIntPipe } from '@nestjs/common';
@Controller('users')
export class UserController {
@Get(':id')
// 自动将 id 转为数字,若转换失败则抛出 400 异常
findOne(@Param('id', ParseIntPipe) id: number) {
return `获取 ID 为 ${id} 的用户`;
}
}
// 全局启用参数验证(main.ts)
import { ValidationPipe } from '@nestjs/common';
app.useGlobalPipes(new ValidationPipe({
whitelist: true, // 过滤掉 DTO 中未定义的属性
forbidNonWhitelisted: true, // 存在未定义属性时抛出异常
transform: true, // 自动将请求数据转换为 DTO 实例
}));
守卫(Guards)
用于权限控制,决定一个请求是否能被控制器处理(比如登录验证、角色权限)。基于执行上下文判断请求是否合法,返回布尔值控制请求是否继续。
作用:实现认证和授权
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
// 模拟验证 token
return !!request.headers.authorization;
}
}
// 控制器级别使用
import { UseGuards } from '@nestjs/common';
@Controller('users')
@UseGuards(AuthGuard) // 该控制器下所有路由都需要验证
export class UserController {}
// 路由级别使用
@Get('profile')
@UseGuards(AuthGuard) // 仅该路由需要验证
getProfile() {
return '用户个人信息';
}
装饰器驱动开发
整个框架基于 TypeScript 装饰器实现,所有核心功能(路由、依赖注入、中间件等)都通过装饰器声明,语法简洁且语义化。
作用:简化代码,提高可读性