在这一篇文章nest的基石-装饰器 中介绍了装饰器,那么今天就看看装饰器在 nest 的具体使用
module
负责组织和封装应用程序组件
一个程序至少有一个根模块(root),一个模块是为了封装一组密切相关的功能,这样的代码结构清晰,便于复用
以 AppModule
为例,本身是一个普通的类,但是加上了 @Module
装饰器之后,就变为了 模块
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
@Module()
装饰器接受一个对象,该对象的属性描述了模块:
名称 | 功能 |
---|---|
providers | 在该模块之间共享的 服务程序 |
controllers | 在该模块中定义的必须被实例化的控制器集合 |
imports | 导出此模块中所需提供程序的导入模块列表 |
exports | 此模块 服务程序 的子集,并且应该在导入此模块的其他模块中可用 |
在 AppModule 中注入了 AppController 与 AppService,那么在 AppController 就可以使用 AppService中的方法,无需实例化 AppService
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
共享模块
使用全局命令直接创建一个 common
和 dogs
资源(包含 module,controller,service)
nest g res common --no-spec
nest g res dogs --no-spec
在 CommonService 中定义方法 getCommon
, 如果我想在让 Dogs 模块也使用这个方法应该怎么做呢?
@Injectable()
export class CommonService {
getCommon(){
return "common"
}
}
默认情况下,别的模块是无法使用本模块的服务的,可以通过 exports 导出服务供其他模块使用
@Module({
controllers: [CommonController],
providers: [CommonService],
exports:[CommonService],
})
export class CommonModule {}
那么在 DogsModule 导入 CommonModule 模块
@Module({
// 导入要使用的模块
imports:[CommonModule],
controllers: [DogsController],
providers: [DogsService],
})
export class DogsModule {}
由于 DogsModule 导入了 CommonModule,同时 CommonModule 又暴露出 CommonService
那么相当于 DogsModule 导入了 CommonService
注入之后就可以直接使用
@Injectable()
export class DogsService {
@Inject()
private readonly commonService: CommonService;
getDogs() {
return 'Dogs' + this.commonService.getCommon();
}
}
如果您必须在所有地方导入相同的模块集,那么每次导入就会变得很啰嗦
使用@Global()
装饰器使模块全局化
在CommonModule 添加 @Global
,使之变为全局模块,那么 DogsModule 就无需导入
@Global()
@Module({
controllers: [CommonController],
providers: [CommonService],
exports:[CommonService],
})
export class CommonModule {}
无需导入也可使用 CommonModule 暴露出来的服务
@Module({
controllers: [DogsController],
providers: [DogsService],
})
export class DogsModule {}
controller
控制器负责处理传入请求并将响应返回给客户端。
以 DogsController 为例
@Controller('dogs')
export class DogsController {
constructor(private readonly dogsService: DogsService) {}
@Get()
getHello(): string {
return this.dogsService.getDogs();
}
}
在 @Controller()
装饰器中指定路径公共前缀 dogs
,并和 Get中的具体路径进行拼接,形成一个完整路径,例如,dogs
的路径前缀与装饰器@Get('breed')
组合将为 GET /dogs/breed
这样的请求生成路由映射。
请求对象
处理程序通常需要访问客户端请求的详细信息。
装饰器 | 请求参数 | 说明 |
---|---|---|
@Param(key?: string) | /:id | req.params / req.params[key] |
@Body(key?: string) | post 请求体 | req.body / req.body[key] |
@Query(key?: string) | get中query参数 | req.query / req.query[key] |
service
service 的作用是处理业务逻辑和数据操作。
controller 接收请求之后,主要逻辑是在 service 中处理
@Injectable()
export class DogsService {
getDogs() {
return 'Dogs'
}
}
在 DogsController
中使用
@Controller('dogs')
export class DogsController {
constructor(private readonly dogsService: DogsService) { }
@Get()
getAll() {
return this.dogsService.getDogs();
}
总结
NestJS 通过模块(Module)、控制器(Controller)和服务(Service)实现了高效、可扩展的应用程序架构:
-
模块(Module) :
- 作用:组织和封装相关组件,如控制器和服务。
- 功能:注册依赖关系,实现模块化设计,共享资源,初始化配置。
-
控制器(Controller) :
- 作用:处理 HTTP 请求和响应。
- 功能:接收请求,调用服务,定义路由。
-
服务(Service) :
- 作用:处理业务逻辑和数据操作。
- 功能:实现核心业务逻辑,与数据存储交互,解耦控制器,复用和共享,依赖注入。
通过这些核心组件,NestJS 实现了高度模块化、可维护和可扩展的应用程序开发。