跳转到主内容
Avatar
GrapeWell

nest学习小记(1)

2025-09-04

Nest MVC 层级 #

nest实现了mvc层级,就是module,view,controller,module接收请求,controller处理请求,view返回数据,所以在通过nest cli创建项目的时候会发现比koa层级更加清晰,koa需要自己去设定层级。

Nest CLI 命令 #

nest cli提供了强大的命令行工具,基本上大部分操作都由nest cli完成

# 新建项目
nest new 项目命
# 创建一个controller
nest g controller aaa
# 创建一个module
nest g module aaa
# 创建完整模块
nest g resource aaa
... 

通过nest cli能帮我们快速创建文件,提高开发效率

路由生成规则 #

nest的路由是根据controller里面的请求方法生成的,例如@Get(),表示\@Get('aaa'),表示\aaa,并且支持Post、Get、Delete等常见的请求方法

IoC 与 DI 概念 #

ioc表示inversion of control,中文名称控制反转,意思就是控制从主动变为被动,例如在使用一个类时,需要先执行new Object(),手动创建一个对象,再对这个对象进行操作,如果有依赖嵌套,那么管理起来很困难,并且这些需要使用到的对象,适合于单例模式,只用创建一次,在实现控制反转后,这个new的过程是自动的。

di表示dependency injection,中文名称依赖注入,什么称之为依赖,某某东西需要某某东西,在代码中例如,controller依赖service,service需要对数据库进行操作,那么又需要依赖数据库(repository)

Nest 中的 IoC 使用 #

nest的ioc使用是通过装饰器完成的,包括@Controller@Service@Module,大致的原理是,项目启动的时候,会扫描模块,控制器,获取类的依赖关系,并通过new创建实例,放在ioc容器中。其中模块是基础的功能组织单元,聚合相关的controller和service 类似于 const controller = new Controller(Service)

使用依赖的两种方式 #

@Controller()
@UseInterceptors(TimeInterceptor)
export class AppController {
  // 构造函数型
  constructor(private readonly appService: AppService) {}

  // 属性型
  @Inject()
  private readonly appService: AppService;
}

提供依赖的三种方式 #

@Module({
  imports: [],
  controllers: [AppController],
  providers: [
    AppService, // 1. 直接写类名
    // 2. useClass等同于直接写类名
    {
      provide: AppService, // token
      useClass: AppService,
    },
    // 3. useValue
    {
      provide: 'person',
      useValue: {
        name: 'aaa',
        age: 20,
      },
    },
    // 4. useFactory temp1
    {
      provide: 'person2',
      useFactory: () => {
        return {
          name: 'bbb',
          desc: 'ccc',
        };
      },
    },
    // 5. useFactory temp2
    {
      provide: 'person3',
      useFactory: (person: { name: string }, appService: AppService) => {
        return {
          name: person.name,
          desc: appService.getHello(),
        };
      },
      inject: ['person', AppService], //可以注入其他东西,来获得一些能力
    },
    // 6. useFactory temp3
    {
      provide: 'person5',
      useFactory: async () => {
        await new Promise((resolve) => {
          setTimeout(resolve, 3000);
        }); // 支持异步方法,这里能进行一些数据请求
        return {
          name: 'bbb',
          desc: 'ccc',
        };
      },
    },
    // 7. useExisting
    {
      provide: 'person4',
      useExisting: 'person2', // 使用已有的provider,类似于改别名
    },
  ],
})
export class AppModule implements NestModule {
  
}

如果provide提供的是字符串,在使用依赖的时候需要使用@Inject('xx')

@Inject('person') private readonly person: { name: string; age: number },