NestJS 后端框架知识点
一、NestJS 简介
1. 什么是 NestJS
NestJS 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的渐进式框架。它基于 TypeScript 构建,结合了 OOP(面向对象编程)、FP(函数式编程)和 FRP(函数响应式编程)的元素。NestJS 提供了一种模块化的方式来组织代码,使开发者能够构建可维护和可测试的应用程序。
2. NestJS 的特点
- TypeScript 支持:内置 TypeScript 支持,提供类型安全
- 模块化架构:基于模块的架构,便于代码组织和维护
- 依赖注入:内置依赖注入容器,简化组件之间的依赖管理
- 装饰器语法:使用装饰器语法,简化代码编写
- 中间件支持:支持全局和路由级中间件
- 异常过滤:统一的异常处理机制
- 管道:用于数据验证和转换
- 守卫:用于权限控制和认证
- 拦截器:用于请求/响应的预处理和后处理
- 与 Express 和 Fastify 兼容:底层可以使用 Express 或 Fastify 作为 HTTP 服务器
- 强大的 CLI:提供命令行工具,简化项目创建和管理
- 丰富的生态系统:提供多种模块和集成
3. NestJS 的优势
- 代码组织:模块化架构使代码更易于组织和维护
- 类型安全:TypeScript 提供编译时类型检查,减少运行时错误
- 可测试性:依赖注入使测试更加容易
- 可扩展性:模块化设计使应用程序易于扩展
- 社区活跃:拥有活跃的社区和丰富的文档
- 企业级应用:适合构建大型企业级应用
二、NestJS 的核心概念
1. 模块 (Module)
模块是 NestJS 应用程序的基本组织单位,用于组织代码并定义组件之间的关系。每个模块都由 @Module() 装饰器标记,包含控制器、提供者和导入的模块。
模块的结构
- controllers:处理 HTTP 请求和响应
- providers:服务、仓库等可注入的依赖
- imports:导入其他模块
- exports:导出模块中的提供者,供其他模块使用
根模块
根模块是应用程序的入口点,通常命名为 AppModule。
2. 控制器 (Controller)
控制器负责处理 HTTP 请求,路由请求到相应的处理方法,并返回响应。控制器使用 @Controller() 装饰器标记,方法使用 HTTP 方法装饰器(如 @Get()、@Post() 等)标记。
3. 提供者 (Provider)
提供者是 NestJS 中的核心概念,包括服务、仓库、工厂等。提供者可以被注入到其他组件中,使用 @Injectable() 装饰器标记。
4. 服务 (Service)
服务是提供者的一种,用于封装业务逻辑。服务通常被注入到控制器中,处理具体的业务操作。
5. 中间件 (Middleware)
中间件是在路由处理之前或之后执行的函数,用于处理请求和响应。中间件可以是全局的或路由级的。
6. 管道 (Pipe)
管道用于数据验证和转换,在请求到达控制器之前执行。管道可以用于验证请求体、查询参数等。
7. 守卫 (Guard)
守卫用于权限控制和认证,在控制器方法执行之前执行。守卫可以用于验证用户身份、检查权限等。
8. 拦截器 (Interceptor)
拦截器用于请求/响应的预处理和后处理,如日志记录、异常处理、响应转换等。
9. 异常过滤器 (Exception Filter)
异常过滤器用于统一处理应用程序中的异常,将异常转换为适当的 HTTP 响应。
10. 自定义装饰器 (Custom Decorator)
NestJS 允许创建自定义装饰器,用于增强代码的可读性和功能。
三、NestJS 项目结构
1. 典型的项目结构
src/
├── app.module.ts # 根模块
├── app.controller.ts # 根控制器
├── app.service.ts # 根服务
├── app.controller.spec.ts # 控制器测试
├── app.service.spec.ts # 服务测试
├── main.ts # 应用程序入口
└── modules/ # 功能模块
├── users/
│ ├── users.module.ts
│ ├── users.controller.ts
│ ├── users.service.ts
│ ├── users.entity.ts
│ └── dto/
│ ├── create-user.dto.ts
│ └── update-user.dto.ts
└── auth/
├── auth.module.ts
├── auth.controller.ts
├── auth.service.ts
└── strategies/
└── jwt.strategy.ts2. 目录说明
- src/:源代码目录
- main.ts:应用程序入口,创建和启动 Nest 应用
- app.module.ts:根模块,组织整个应用的模块结构
- app.controller.ts:根控制器,处理根路径的请求
- app.service.ts:根服务,提供基础服务
- modules/:功能模块目录,按业务功能划分
- dto/:数据传输对象,用于请求和响应的数据结构
- entity/:数据库实体,映射数据库表结构
- strategies/:认证策略,如 JWT 策略
四、NestJS 常用功能
1. 路由
NestJS 使用装饰器定义路由,支持参数路由、查询参数、请求体等。
基本路由
@Controller('users')
export class UsersController {
@Get()
findAll() {
return 'All users';
}
@Get(':id')
findOne(@Param('id') id: string) {
return `User ${id}`;
}
@Post()
create(@Body() createUserDto: CreateUserDto) {
return 'Create user';
}
@Put(':id')
update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
return `Update user ${id}`;
}
@Delete(':id')
remove(@Param('id') id: string) {
return `Remove user ${id}`;
}
}2. 依赖注入
NestJS 使用依赖注入容器管理组件之间的依赖关系。
服务注入
@Injectable()
export class UsersService {
private users = [];
findAll() {
return this.users;
}
findOne(id: string) {
return this.users.find(user => user.id === id);
}
create(user: CreateUserDto) {
this.users.push(user);
return user;
}
}
@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}
@Get()
findAll() {
return this.usersService.findAll();
}
}3. 数据验证
NestJS 使用管道进行数据验证,通常结合 class-validator 库。
DTO 定义
import { IsString, IsEmail, IsNotEmpty } from 'class-validator';
export class CreateUserDto {
@IsString()
@IsNotEmpty()
name: string;
@IsEmail()
email: string;
@IsString()
@IsNotEmpty()
password: string;
}使用管道
@Post()
create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}4. 认证与授权
NestJS 支持多种认证策略,如 JWT、OAuth 等。
JWT 认证
// auth.module.ts
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { JwtStrategy } from './strategies/jwt.strategy';
@Module({
imports: [
JwtModule.register({
secret: 'secretKey',
signOptions: { expiresIn: '1h' },
}),
],
providers: [AuthService, JwtStrategy],
controllers: [AuthController],
})
export class AuthModule {}
// jwt.strategy.ts
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: 'secretKey',
});
}
async validate(payload: any) {
return { userId: payload.sub, username: payload.username };
}
}
// 使用守卫
import { UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Controller('users')
export class UsersController {
@UseGuards(AuthGuard('jwt'))
@Get()
findAll() {
return this.usersService.findAll();
}
}5. 数据库集成
NestJS 支持多种数据库,如 PostgreSQL、MySQL、MongoDB 等。
TypeORM 集成
// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersModule } from './users/users.module';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'password',
database: 'nestjs',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
UsersModule,
],
})
export class AppModule {}
// users.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
@Column()
password: string;
}
// users.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { User } from './users.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}6. 配置管理
NestJS 提供了配置模块,用于管理应用程序配置。
配置模块使用
// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
],
})
export class AppModule {}
// 使用配置
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class AppService {
constructor(private configService: ConfigService) {}
getDatabaseHost() {
return this.configService.get('DATABASE_HOST');
}
}7. 日志
NestJS 内置了日志系统,支持不同级别的日志。
日志使用
import { Injectable, Logger } from '@nestjs/common';
@Injectable()
export class UsersService {
private readonly logger = new Logger(UsersService.name);
findAll() {
this.logger.log('Finding all users');
return this.users;
}
}8. 测试
NestJS 支持单元测试和集成测试,使用 Jest 作为测试框架。
测试示例
// users.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { UsersService } from './users.service';
describe('UsersService', () => {
let service: UsersService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UsersService],
}).compile();
service = module.get<UsersService>(UsersService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
it('should return all users', () => {
expect(service.findAll()).toEqual([]);
});
});五、NestJS 最佳实践
1. 代码组织
- 模块化设计:按功能划分模块,每个模块包含相关的控制器、服务和实体
- 单一职责:每个组件只负责一个功能
- 依赖注入:使用依赖注入管理组件之间的依赖
- DTO 模式:使用 DTO 定义请求和响应的数据结构
2. 性能优化
- 数据库优化:使用索引、批量操作、连接池等
- 缓存:使用 Redis 等缓存机制
- 异步操作:使用 async/await 和 Promise
- 代码分割:按需加载模块
3. 安全
- 认证与授权:使用 JWT 或 OAuth 进行认证
- 输入验证:使用管道进行数据验证
- CSRF 保护:防止跨站请求伪造
- CORS 配置:正确配置跨域资源共享
- 密码加密:使用 bcrypt 等库加密密码
4. 部署
- 容器化:使用 Docker 容器化应用
- 环境变量:使用环境变量管理配置
- CI/CD:使用 GitHub Actions 等工具实现持续集成和部署
- 监控:使用 Prometheus、Grafana 等工具监控应用
六、NestJS 生态系统
1. 核心模块
- @nestjs/common:核心功能模块
- @nestjs/core:核心运行时
- @nestjs/platform-express:Express 适配器
- @nestjs/platform-fastify:Fastify 适配器
2. 常用模块
- @nestjs/config:配置管理
- @nestjs/jwt:JWT 认证
- @nestjs/passport:Passport 集成
- @nestjs/typeorm:TypeORM 集成
- @nestjs/mongoose:MongoDB 集成
- @nestjs/serve-static:静态文件服务
- @nestjs/swagger:API 文档
3. 工具
- Nest CLI:命令行工具,用于创建和管理项目
- Swagger:API 文档生成工具
- TypeORM:ORM 框架,用于数据库操作
- Mongoose:MongoDB ODM
- Passport:认证中间件
4. 社区资源
- NestJS 官网:https://nestjs.com/
- NestJS 文档:https://docs.nestjs.com/
- NestJS GitHub:https://github.com/nestjs/nest
- NestJS 社区:https://discord.gg/G7Qnnhy
七、NestJS 与其他框架的比较
1. NestJS vs Express
- Express:轻量级框架,灵活性高,适合小型应用
- NestJS:基于 Express,提供更结构化的架构,适合大型应用
2. NestJS vs Koa
- Koa:Express 的继任者,更轻量,使用 async/await
- NestJS:提供更完整的功能集和更结构化的架构
3. NestJS vs AdonisJS
- AdonisJS:全功能框架,提供 ORM、认证等
- NestJS:更现代,基于 TypeScript,生态系统更丰富
八、总结
NestJS 是一个功能强大、结构清晰的 Node.js 后端框架,它结合了 TypeScript 的类型安全和模块化架构的优势,使开发者能够构建可维护、可测试和可扩展的应用程序。通过掌握 NestJS 的核心概念和最佳实践,你可以构建高质量的后端服务,满足现代应用的需求。
作为一名后端开发者,学习 NestJS 将为你提供一种现代化的开发方式,帮助你更高效地构建和维护后端应用。NestJS 的生态系统不断发展,社区活跃,是构建企业级应用的理想选择。