nest学习记录 一 基础概念

学习小册:nest通关秘籍

Nest基础概念

controller 路由模块

controller 的方法叫做 handler, 是处理路由和解析请求参数的。

service 业务逻辑处理模块

service 里做业务逻辑的具体实现,比如操作数据库等

Module 模块

像userController和userService,跟bookController,bookSerivce都是属于不同的模块,所以引入了模块的概念,通过@Module声明模块,再通过imports,controllers,providers,exports指明依赖等信息。

dto:data transfer object,数据传输对象,用于封装请求体里数据的对象
entity:对应数据库表的实体
MVC 架构

在这里插入图片描述

nest 应用跑起来后,会从 AppModule 开始解析,初始化 IoC 容器,加载所有的 service 到容器里,
然后解析 controller 里的路由,接下来就可以接收请求了。这种架构叫做 MVC 模式,也就是 model、view、controller
controller 接收请求参数,交给 model 处理(model 就是处理 service 业务逻辑,处理 repository 数据库访问),然后返回 view,也就是响应。

AOP 面向切面编程,在多个请求响应流程中可以复用的逻辑,比如日志记录等

通用逻辑的处理,如中间件,guide,Interceptor,pipe,filter

IOC 反转控制或者叫依赖注入,只要声明依赖,运行时 Nest 会自动注入依赖的实例

IOC之前学习java的时候就有了解。

将手动创建对象实例的操作交给工具去,我们只需要声明对应的依赖关系。
程序启动的时候,工具就会扫描依赖关系,将需要的实例创建放到一个容器中。这种依赖注入就是Dependency Injection,简称DI

从主动创建到被动等待依赖注入,就是Inverse of Controler(IOC)反转控制

  • @Injectable
    比如Service类上面的@Injectable,就是声明这个类可注入到别的类,也可被注入别的类。比如AService中可以注入BService。
  • @Controller,也表示这个类可以被注入,nest也会把它放到ioc里面。

使用IOC容器的时候,可以通过@Inject(xxService)属性声明的方式,也可以使用构造函数参数注入的方式
constructor(private radobly xxService xxx){}

  • @Module声明模块,如
    在这里插入图片描述

  • imports是 需要引入的模块,比如AModule依赖BModule中的某些exports

  • controller是声明路由

  • providers是声明以被注入,也可以注入到其他对象的Service可,providers声明后,便可以在当前module下注入,比如上述AppModule声明了JenkinsService后,就可以在AppService中注入该依赖。

  • exports: 导出的Service(提供给imports[AppModule]的模块用),比如上述的AppService,这时候有BModule中的imports引入AppModule的时候,就不需要在provider中声明AppService,也可以在BService中使用AppService

  • 此外还有全局Service,这样不用声明依赖也可以在任何地方注入。

provider

Nest实现了IOC容器,从入口模块开始扫描,分析Module的依赖关系,自动把对应的Provider注入到目标对象。如
在这里插入图片描述
另一种写法
在这里插入图片描述
provide声明该对象特殊的token,useClass表示创建实例使用的类。
此外可以用字符串,这样的话在生命的时候也需要使用对应的字符串token

在这里插入图片描述
在这里插入图片描述
除此之外还跟java一样可以自定义Bean容器
在这里插入图片描述
使用的时候同注入其他依赖一样即可。
在这里插入图片描述
此外还支持使用useFactory+inject来注入其他的provider
在这里插入图片描述
这其实就是实现一个Person3的类,然后里面依赖了persion和AppService。
此外还支持异步,指定别名,比如TypeOrmModule就是通过useFactory根据传入的options来动态创建数据库连接对象

AOP架构

切面,之前学习java的时候也有了解。就是对通用逻辑的一些封装,使他可以拦截某些handle,比如给参数对象注入page,pageSize,给Insert update的handle的参数对象注入updateUser,updateTime等通用逻辑
nest也实现了一套AOP逻辑。

  • Nest AOP 对一些通用逻辑进行封装,而不影响业务逻辑
    • middleware guide interceptor ExceotionFilter pipe管道
    • middleware express的中间件,可以在请求前后拦截。
    • Interceptro 拦截器, 可以在请求前后拦截,与middleware不同的是,middleware拿不到调用的controller和对应的方法,而拦截器可以,可以通过这个给对应的controller和handle加一些元数据。
    • guide 守卫,在请求前拦截,一般用于鉴权
    • pipe 管道 主要对前端传入参数进行验证,转换等。
    • ExceptionFilter 异常处理,对整个服务抛出的异常进行俘获,已友好的方式返回前端。
    • 上述五种都可以作用于全局或者单个路由,这就是AOP的好处,他们的调用顺序:请求->guide->Interceptor(多个拦截器会依次执行) -> pipe -> handle -> interceptor -> ExceptionFilter(全局异常兜底)
    • middleware是express的概念,nest只是继承了一下,他在最外层调用,所以最终的顺序是:middleware->guide->Interceptro->pipe->处理请求->interceptor->middleware

在这里插入图片描述

  • Nest基于express做了一层封装,实现了IOC,AOP,MVC等架构思想
  • MVC 就是 Model、View Controller 的划分,请求先经过 Controller,然后调用 Model 层的 Service、Repository 完成业务逻辑,最后返回对应的 View。
  • IOC 是指 Nest 会自动扫描带有 @Controller、@Injectable 装饰器的类,创建它们的对象,并根据依赖关系自动注入它依赖的对象,免去了手动创建和组装对象的麻烦。
  • AOP 则是把通用逻辑抽离出来,通过切面的方式添加到某个地方,可以复用和动态增删切面逻辑。
  • Nest 的Middleware、Guard、Interceptor、Pipe、ExceptionFilter 都是 AOP 思想的实现,只不过是不同位置的切面,它们都可以灵活的作用在某个路由或者全部路由,这就是 AOP 的优势。
Nest所有装饰器

在java中叫注解,在Nest中叫装饰器,比如java的@RestController,Nest的@Controller。

Nest提供了一套模块系统,通过@Module声明模块
通过@Controller和@Injectable声明其中的controller和provider。

其中,@Injectable可以作用于任何的class

依赖注入@Inject(xxx),这个xx是制定注入的token名

如果遇到没有容器中没有的对象,注入就会报错,这时候可以再使用一个装饰器@Optional来声明是可选注入。就不会报错
在这里插入图片描述
@Global声明是全局module,这样他生命的provider就可以在全局任何地方注入。

@Catch和@UseFilters是一套可以用来拦截异常报错的组合装饰器。

此外还有@UseGuards,@UseInterceptors @UsePipes等装饰器。

还有@Post @Get @Put @Delete等声明方法方式,@Body @Param @Query @Header获取前端参数,请求头等

此外,handler和class可以通过@SetMetadata指定原数据

在这里插入图片描述
然后可以在guide或者intercleptor中取出来,从而进行一些判断。
在这里插入图片描述
此外可以通过@Req @Request @Res @Responser拿到对应的req, res对象。

@Rediret 在这里插入图片描述
重定向

nest装饰器总结

@Module: 声明 Nest 模块
@Controller:声明模块里的 controller
@Injectable:声明模块里可以注入的 provider
@Inject:通过 token 手动指定注入的 provider,token 可以是 class 或者 string
@Optional:声明注入的 provider 是可选的,可以为空
@Global:声明全局模块
@Catch:声明 exception filter 处理的 exception 类型
@UseFilters:路由级别使用 exception filter
@UsePipes:路由级别使用 pipe
@UseInterceptors:路由级别使用 interceptor
@SetMetadata:在 class 或者 handler 上添加 metadata
@Get、@Post、@Put、@Delete、@Patch、@Options、@Head:声明 get、post、put、delete、patch、options、head 的请求方式
@Param:取出 url 中的参数,比如 /aaa/:id 中的 id
@Query: 取出 query 部分的参数,比如 /aaa?name=xx 中的 name
@Body:取出请求 body,通过 dto class 来接收
@Headers:取出某个或全部请求头
@Session:取出 session 对象,需要启用 express-session 中间件
@HostParm: 取出 host 里的参数
@Req、@Request:注入 request 对象
@Res、@Response:注入 response 对象,一旦注入了这个 Nest 就不会把返回值作为响应了,除非指定 passthrough 为true
@Next:注入调用下一个 handler 的 next 方法
@HttpCode: 修改响应的状态码
@Header:修改响应头
@Redirect:指定重定向的 url
@Render:指定渲染用的模版引擎

自定义装饰器

比如SetMetadata

import {
    SetMetadata } from '@nestjs/common';

export const TestAA = (...args: string[]) => {
   
  return SetMetadata('role', args);
};

使用

 @Get()
  @Version('1')
  @TestAA('admin')
  getHello(): string {
   
    return this.appService.getHello();
  }


在这里插入图片描述
效果一样

组装装饰器,

export const TestBB = (path, args: string[]) => {
   
  return applyDecorators(Get(path), SetMetadata('role', args), UseGuards());
};

效果跟

@Get('')
@SetMetadata('')
@UseGuards()
xxx(){
   }

一样

实现@Queyr @Headers装饰器。
本质就是通过createParamDecorator创建一个函数,通过ctx获取req对象,然后通过req获取里面的值,如

export const MyHeaders = createParamDecorator(
  (key: string, ctx: ExecutionContext) => {
   
    const req = ctx.switchToHttp().getRequest();
    return key ? req.headers[key.toLowerCase()] : req.headers;
  },
);

export const MyQuery = createParamDecorator(
  (key: string, ctx: ExecutionContext) => {
   
    const req = ctx.switchToHttp().getRequest();
    return req.query[key];
  },
);

效果跟@Headers和@Query是一样的。

Metadata 和 Reflector

对类,方法,属性,方法参数我们可以设置元数据,
Reflect支持defineMetadata和getMetadata设置和获取某个类的元数据。

Reflect.defineMetadata(metadataKey, metadataValue, class1) //给类加元数据
Reflect.defineMetadata(metadataKey, metadataValue, c
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coderlin_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值