NestJS架构
NestJS 是一个基于 Node.js 的渐进式框架,用于构建高效、可扩展的服务器端应用程序。它采用模块化设计,结合了面向对象编程、函数式编程和响应式编程的优势,同时底层默认集成 Express 或 Fastify,为开发者提供了灵活的选择。
核心架构设计
NestJS 的核心架构建立在几个关键概念之上:
- 模块系统:应用程序被组织成模块,每个模块封装特定功能
- 依赖注入:通过装饰器实现松耦合的组件管理
- 控制器:处理 HTTP 请求并返回响应
- 提供者:可注入的服务、仓库等业务逻辑组件
- 中间件:处理请求/响应周期的功能
- 异常过滤器:集中处理应用程序异常
- 管道:数据验证和转换
- 守卫:路由访问控制
- 拦截器:在方法执行前后添加额外逻辑
模块系统详解
模块是 NestJS 应用的基本组织单元,使用 @Module()
装饰器定义:
@Module({
imports: [OtherModule],
controllers: [UserController],
providers: [UserService],
exports: [UserService]
})
export class UserModule {}
imports
:导入其他模块controllers
:注册控制器providers
:注册提供者(服务)exports
:暴露提供者给其他模块使用
依赖注入机制
NestJS 的依赖注入系统是其架构的核心优势。通过构造函数注入的方式实现:
@Injectable()
export class UserService {
constructor(private readonly repository: UserRepository) {}
async findAll(): Promise<User[]> {
return this.repository.find();
}
}
在控制器中使用服务:
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
async findAll(): Promise<User[]> {
return this.userService.findAll();
}
}
控制器与路由
控制器负责处理传入请求并返回响应:
@Controller('cats')
export class CatsController {
@Get()
findAll(): string {
return 'This action returns all cats';
}
@Get(':id')
findOne(@Param('id') id: string): string {
return `This action returns a #${id} cat`;
}
@Post()
@HttpCode(204)
create() {
return 'This action adds a new cat';
}
}
提供者与服务
提供者是 NestJS 中业务逻辑的主要承载者:
@Injectable()
export class NotificationService {
private readonly clients: Client[] = [];
addClient(client: Client) {
this.clients.push(client);
}
sendAll(message: string) {
this.clients.forEach(client => client.send(message));
}
}
中间件系统
中间件可以处理请求和响应:
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log(`Request... ${req.method} ${req.path}`);
next();
}
}
在模块中应用:
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('*');
}
}
异常处理
NestJS 提供了异常过滤器机制:
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const status = exception.getStatus();
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
message: exception.message
});
}
}
在控制器中使用:
@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
throw new ForbiddenException();
}
管道与数据验证
管道用于数据转换和验证:
@Injectable()
export class ValidationPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
if (!value) {
throw new BadRequestException('No data submitted');
}
return value;
}
}
使用内置的验证管道:
@Post()
async create(
@Body(new ValidationPipe()) createUserDto: CreateUserDto
) {
// ...
}
守卫与认证
守卫用于路由访问控制:
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
return validateRequest(request);
}
}
在控制器中使用:
@UseGuards(AuthGuard)
@Controller('profile')
export class ProfileController {}
拦截器
拦截器可以在方法执行前后添加逻辑:
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
console.log('Before...');
const now = Date.now();
return next
.handle()
.pipe(tap(() => console.log(`After... ${Date.now() - now}ms`)));
}
}
应用拦截器:
@UseInterceptors(LoggingInterceptor)
@Controller('users')
export class UserController {}
微服务支持
NestJS 原生支持微服务架构:
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.TCP,
options: { host: 'localhost', port: 3001 }
}
);
await app.listen();
WebSocket 集成
NestJS 提供了对 WebSocket 的良好支持:
@WebSocketGateway()
export class EventsGateway {
@WebSocketServer()
server: Server;
@SubscribeMessage('events')
handleEvent(client: any, data: string): string {
return data;
}
}
测试策略
NestJS 提供了完善的测试工具:
describe('UserController', () => {
let userController: UserController;
let userService: UserService;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
controllers: [UserController],
providers: [UserService],
}).compile();
userService = moduleRef.get<UserService>(UserService);
userController = moduleRef.get<UserController>(UserController);
});
describe('findAll', () => {
it('should return an array of users', async () => {
const result = ['test'];
jest.spyOn(userService, 'findAll').mockImplementation(() => result);
expect(await userController.findAll()).toBe(result);
});
});
});
配置管理
NestJS 推荐使用 ConfigModule 进行配置管理:
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: '.development.env',
}),
],
})
export class AppModule {}
使用配置:
@Injectable()
export class DatabaseService {
constructor(private configService: ConfigService) {
const dbUser = this.configService.get<string>('DATABASE_USER');
}
}
数据库集成
NestJS 支持多种 ORM 集成,以 TypeORM 为例:
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'test',
entities: [User],
synchronize: true,
}),
TypeOrmModule.forFeature([User]),
],
})
export class AppModule {}
定义实体:
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
firstName: string;
@Column()
lastName: string;
}
性能优化
NestJS 应用可以通过多种方式优化性能:
- 使用 FastifyAdapter 替代默认的 Express
- 实现缓存策略
- 使用压缩中间件
- 启用集群模式
- 优化依赖注入树
启用 Fastify:
async function bootstrap() {
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter()
);
await app.listen(3000);
}
部署策略
NestJS 应用可以部署在各种环境中:
- 传统服务器部署
- 容器化部署(Docker)
- 无服务器架构(Serverless)
- 平台即服务(PaaS)
Docker 部署示例:
FROM node:16-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/main"]
生态系统与插件
NestJS 拥有丰富的生态系统:
@nestjs/swagger
- API 文档生成@nestjs/graphql
- GraphQL 支持@nestjs/bull
- 队列处理@nestjs/terminus
- 健康检查@nestjs/schedule
- 任务调度
Swagger 集成示例:
const config = new DocumentBuilder()
.setTitle('Cats example')
.setDescription('The cats API description')
.setVersion('1.0')
.addTag('cats')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
架构最佳实践
- 遵循单一职责原则设计模块
- 使用领域驱动设计(DDD)组织代码结构
- 实现清晰的层次划分(控制器-服务-仓库)
- 保持业务逻辑与框架解耦
- 编写全面的单元测试和集成测试
领域驱动设计示例结构:
src/
├── users/
│ ├── entities/
│ ├── repositories/
│ ├── services/
│ ├── controllers/
│ └── users.module.ts
├── products/
│ ├── entities/
│ ├── repositories/
│ ├── services/
│ ├── controllers/
│ └── products.module.ts
└── shared/
├── infrastructure/
└── common/
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn