Appearance
NestJS基础概念
NestJS是一个渐进式的Node.js框架,用于构建高效、可扩展的服务端应用程序。它结合了OOP、FP和FRP的元素,深受Angular的启发。
核心架构
依赖注入 (Dependency Injection)
NestJS使用内置的依赖注入系统来管理类之间的依赖关系。
typescript
import { Injectable } from '@nestjs/common';
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
create(cat: Cat) {
this.cats.push(cat);
}
findAll(): Cat[] {
return this.cats;
}
}
在控制器中注入服务:
typescript
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';
@Controller('cats')
export class CatsController {
constructor(private catsService: CatsService) {}
@Post()
async create(@Body() createCatDto: Cat) {
this.catsService.create(createCatDto);
}
@Get()
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}
装饰器 (Decorators)
NestJS使用装饰器来添加元数据到类和方法:
typescript
import {
Controller,
Get,
Post,
Put,
Delete,
Param,
Body,
Query,
Headers,
Req,
Res
} from '@nestjs/common';
import { Request, Response } from 'express';
@Controller('users')
export class UsersController {
// GET请求
@Get()
findAll(@Query() query: any) {
return `Returning all users with query: ${JSON.stringify(query)}`;
}
// GET请求带参数
@Get(':id')
findOne(@Param('id') id: string, @Headers('authorization') auth: string) {
return `Returning user with id: ${id}, auth: ${auth}`;
}
// POST请求
@Post()
create(@Body() createUserDto: any) {
return `Creating user with data: ${JSON.stringify(createUserDto)}`;
}
// 使用原生请求和响应对象
@Get('raw/:id')
findOneRaw(@Param('id') id: string, @Req() req: Request, @Res() res: Response) {
res.status(200).send(`User ID: ${id}`);
}
}
模块系统
模块定义
模块是带有@Module()装饰器的类,它定义了应用程序的结构:
typescript
import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';
import { CatsModule } from './cats/cats.module';
@Module({
imports: [CatsModule], // 导入其他模块
controllers: [CatsController], // 该模块的控制器
providers: [CatsService], // 该模块的服务
exports: [CatsService], // 导出供其他模块使用的提供者
})
export class AppModule {}
功能模块
typescript
// cats/cats.module.ts
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
@Module({
controllers: [CatsController],
providers: [CatsService],
exports: [CatsService], // 导出服务供其他模块使用
})
export class CatsModule {}
共享模块
typescript
// database/database.module.ts
import { Module } from '@nestjs/common';
import { DatabaseService } from './database.service';
@Module({
providers: [DatabaseService],
exports: [DatabaseService],
})
export class DatabaseModule {}
控制器 (Controllers)
控制器负责处理传入的请求并返回响应给客户端。
typescript
import {
Controller,
Get,
Post,
Body,
Param,
Query,
Put,
Delete,
HttpStatus,
HttpCode,
Header,
Redirect,
Render,
Res,
UseInterceptors
} from '@nestjs/common';
import { Response } from 'express';
import { CatsService } from './cats.service';
@Controller('cats')
export class CatsController {
constructor(private catsService: CatsService) {}
@Get()
@HttpCode(HttpStatus.OK)
@Header('Cache-Control', 'none')
findAll(): string {
return 'This action returns all cats';
}
@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version: string) {
if (version && version === '5') {
return { url: 'https://docs.nestjs.com/v5/' };
}
}
@Get(':id')
@Render('cats')
findOne(@Param('id') id: string) {
return { id: id };
}
@Post()
@UseInterceptors(SomeInterceptor)
create(@Body() createCatDto: any) {
return this.catsService.create(createCatDto);
}
@Get('stream')
stream(@Res() res: Response) {
res.setHeader('Content-Type', 'text/plain');
res.status(HttpStatus.OK);
res.send('Streamed response');
}
}
提供者 (Providers)
提供者是NestJS的基本构建块,包括服务、仓库、工厂、助手等。
服务提供者
typescript
import { Injectable, Scope } from '@nestjs/common';
@Injectable()
export class CatsService {
constructor() {}
getHello(): string {
return 'Hello from CatsService';
}
}
// 请求范围的提供者
@Injectable({ scope: Scope.REQUEST })
export class RequestScopedService {
constructor() {}
}
工厂提供者
typescript
import { Injectable } from '@nestjs/common';
@Injectable()
export class ConfigService {
get(key: string): string {
return process.env[key];
}
}
// 工厂提供者
export const configProvider = {
provide: 'CONFIG_SERVICE',
useFactory: (configService: ConfigService) => {
return {
port: configService.get('PORT') || 3000,
host: configService.get('HOST') || 'localhost',
};
},
inject: [ConfigService],
};
别名提供者
typescript
export const loggerAliasProvider = {
provide: 'CUSTOM_LOGGER',
useExisting: 'LOGGER',
};
生命周期钩子
NestJS提供了一些生命周期钩子,允许您在特定时间点执行代码:
typescript
import { Injectable, OnModuleInit, OnModuleDestroy, OnApplicationBootstrap } from '@nestjs/common';
@Injectable()
export class CatsService implements OnModuleInit, OnModuleDestroy, OnApplicationBootstrap {
async onModuleInit() {
console.log('Module initialized.');
}
async onApplicationBootstrap() {
console.log('Application is bootstrapped.');
}
async onModuleDestroy() {
console.log('Module destroyed.');
}
}
异步模块初始化
typescript
import { Module, DynamicModule } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { ConfigModule } from './config/config.module';
@Module({
imports: [DatabaseModule],
})
export class AppModule {
static async forRoot(): Promise<DynamicModule> {
const configService = new ConfigService();
await configService.loadConfig(); // 异步加载配置
return {
module: AppModule,
imports: [
DatabaseModule.forRoot(configService.getDatabaseConfig()),
ConfigModule,
],
providers: [
{
provide: 'CONFIG_SERVICE',
useValue: configService,
},
],
exports: ['CONFIG_SERVICE'],
};
}
}
作用域和注入范围
typescript
import { Injectable, Scope } from '@nestjs/common';
// 默认是单例
@Injectable()
export class CatsService {}
// 请求范围 - 每个请求创建一个实例
@Injectable({ scope: Scope.REQUEST })
export class RequestService {
private readonly id = Math.random();
getId() {
return this.id;
}
}
// 过渡范围
@Injectable({ scope: Scope.TRANSIENT })
export class TransientService {
private readonly id = Math.random();
getId() {
return this.id;
}
}
自定义提供者
typescript
// 值提供者
export const connectionProvider = {
provide: 'CONNECTION',
useValue: {
host: 'localhost',
port: 5432,
},
};
// 类提供者
export const loggerProvider = {
provide: 'LOGGER',
useClass: CustomLogger,
};
// 工厂提供者
export const httpProvider = {
provide: 'HTTP_SERVICE',
useFactory: (configService: ConfigService) => {
const isDev = configService.get('ENV') === 'development';
return isDev ? new DevHttpService() : new ProductionHttpService();
},
inject: [ConfigService],
};
应用程序上下文
typescript
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
// 创建应用实例
const app = await NestFactory.create(AppModule);
// 设置全局前缀
app.setGlobalPrefix('api');
// 启用CORS
app.enableCors();
// 启用热重载
if (process.env.NODE_ENV === 'development') {
app.enableShutdownHooks();
}
// 监听端口
await app.listen(3000);
}
bootstrap();
这些基础概念构成了NestJS的核心,理解它们对于构建复杂的应用程序至关重要。