Nestjs之装饰器

183 阅读5分钟

Nest的功能大多是通过装饰器来使用的,接下来把这些装饰器都使用一遍。
首先,创建一个新的nest项目:

nest new decorator -p pnpm

Nest提供了一套模块系统,通过@Module声明模块: image.png

通过@Controller、@Injectable分别声明其中的controller和provider: image.png image.png

@Inject

provider注入:
构造器注入: image.png

属性注入: image.png 属性注入需要指定注入的token,可以是class,也可能是string,上一张图片介绍的就是class做为token,string作为token如下: image.png

这里需要app.module.ts的provides中声明这个provider: image.png

@Optional

如果有些注入的依赖没有,创建对象的时候会报错。这是为了避免报错可以将其设置为可选的,这时就需要使用@Optional装饰器来声明,这样没有对应的provider也能正常创建这个对象。
首先我们在Controller注入一个yangmy的属性: image.png

但是我们在module中并未提供这个: image.png 这时控制台就会报错: image.png

此时我们在属性注入的@Inject('yangmy')上添加一个@Optional将其设置为可选的,就不会有这个报错: image.png

@Global

如果一个模块被很多地方都引用了,可以使用@Global将其设置为全局模块这样它exportsprovider就可以直接注入使用: image.png

@Catch、@UseFilters

filter是处理抛出的未捕获异常,通过@Catch来指定处理的异常: image.png 然后通过@UseFilters应用到handler上: image.png 启动项目,刷新页面: image.png

@UseGuards、@UseInterceptors、@UsePipes

这三种用法和上面的@UseFilters用法一样,需要先建立对应的provider,然后再使用对应的装饰器去调用。

@Param、@Query

image.png image.png image.png @Param是获取路径中的参数,而@Query是获取url问号中的参数

@Post、@Body

在post请求中,@Body是获body请求体的参数: image.png

一般使用dto的class来接受请求体里的参数: image.png

使用postman发送一个请求,可以看到请求成功,且控制台也打印出了对应的参数: image.png image.png

@Put、@Delete、@Patch、@Options、@Head

分别接受put、delete、patch、options、head的请求

@SetMetadata

handler和class可以通过@SetMetadata指定metadata: image.png 我们指定了一个class Metadata,一个method Metadata, 然后我们在guard或者interceptor中取出来: image.png

刷新页面,查看打印的内容: image.png

@Headers

通过装饰器获取某个请求头或者全部的请求头: image.png

@Ip

可以通过这个,获取到当前请求的ip: image.png

@Session

通过@Session可以获取到session对象:
image.png 要使用session,需要先安装一个express中间件:

npm install express-session

之后在main.ts中引入并启用:

image.png 指定加密的密钥,以及session生效的时间,然后刷新页面: image.png 返回了set-cookie的响应头,设置了cookie,包含sid,也就是sessionid.
之后每次请求接口都会自动带上这个cookie:

image.png

同时,控制台也会根据我们的log打印这个session image.png

之后我们就可以通过在session中存储信息,设置后其他接口在请求时也会带上这个存储的信息:

image.png

@HostParam

用于取域名部分的参数:
首先创建一个controller

nest g co aaa --no-spec --flat

然后修改aaa.controller.ts指定生效的路径: image.png 接着访问路由127.0.0.1:3000,可以看到能够正常访问这个新的路径: image.png 但是如果你使用localhost:3000,这样的地址访问就不会访问到这个controller了,会发现只有host满足xx.0.0.1的时候才会路由到这个controller

host里的参数就可以通过@HostParam取出来: image.png image.png

@Req 和 @Request

这两个装饰器是同一个东西,可以获取到request里的内容,当注入request对象后可以手动获取到请求中的参数: image.png

@Res 和 @Response

这两个也是一个东西,只不过response有点特殊,在注入它的时候需要手动end,不然服务会一直卡着没有响应: image.png image.png

这样设计是为了避免你自己返回的响应和nest返回的响应冲突。
如果自己不想手动end,还可以通过向@Res中传入passthrough参数,来返回响应: image.png image.png

@HttpCode

可以通过这个来修改请求的状态码: image.png image.png

@Header

可以通过@Header来修改response header: image.png image.png

@Redirect

通过这个来指定路由重定向的url: image.png

总结

  • @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: 取出queryb部分的参数,比如?name=hu&age=12
  • @Body: 取出请求body,通过dto class来接收
  • @Headers: 取出某个或者全部请求头
  • @Session: 取出session对象,需要启用express-session中间件
  • @HostParam: 取出host里的参数
  • @Req、@Request: 注入request对象
  • @Res、@Response:注入 response 对象,一旦注入了这个 Nest 就不会把返回值作为响应了,除非指定 passthrough 为true
  • @Next:注入调用下一个 handler 的 next 方法
  • @HttpCode: 修改响应的状态码
  • @Header:修改响应头
  • @Redirect:指定重定向的 url