nest核心 - module/controller/service

231 阅读3分钟

在这一篇文章nest的基石-装饰器 中介绍了装饰器,那么今天就看看装饰器在 nest 的具体使用

module

负责组织和封装应用程序组件

一个程序至少有一个根模块(root),一个模块是为了封装一组密切相关的功能,这样的代码结构清晰,便于复用

image.png

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!';
  }
}

共享模块

image.png

使用全局命令直接创建一个 commondogs 资源(包含 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

控制器负责处理传入请求并将响应返回给客户端。

image.png

以 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)/:idreq.params / req.params[key]
@Body(key?: string)post 请求体req.body / req.body[key]
@Query(key?: string)get中query参数req.query / req.query[key]

code.png

service

service 的作用是处理业务逻辑和数据操作。
controller 接收请求之后,主要逻辑是在 service 中处理

image.png

@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)实现了高效、可扩展的应用程序架构:

  1. 模块(Module)

    • 作用:组织和封装相关组件,如控制器和服务。
    • 功能:注册依赖关系,实现模块化设计,共享资源,初始化配置。
  2. 控制器(Controller)

    • 作用:处理 HTTP 请求和响应。
    • 功能:接收请求,调用服务,定义路由。
  3. 服务(Service)

    • 作用:处理业务逻辑和数据操作。
    • 功能:实现核心业务逻辑,与数据存储交互,解耦控制器,复用和共享,依赖注入。

通过这些核心组件,NestJS 实现了高度模块化、可维护和可扩展的应用程序开发。