Nest的功能大多是通过装饰器来使用的,接下来把这些装饰器都使用一遍。
首先,创建一个新的nest项目:
nest new decorator -p pnpm
Nest提供了一套模块系统,通过@Module声明模块:
通过@Controller、@Injectable分别声明其中的controller和provider:
@Inject
provider注入:
构造器注入:
属性注入:
属性注入需要指定注入的token,可以是class,也可能是string,上一张图片介绍的就是class做为token,string作为token如下:
这里需要app.module.ts的provides中声明这个provider:
@Optional
如果有些注入的依赖没有,创建对象的时候会报错。这是为了避免报错可以将其设置为可选的,这时就需要使用@Optional装饰器来声明,这样没有对应的provider也能正常创建这个对象。
首先我们在Controller注入一个yangmy的属性:
但是我们在module中并未提供这个:
这时控制台就会报错:
此时我们在属性注入的@Inject('yangmy')上添加一个@Optional将其设置为可选的,就不会有这个报错:
@Global
如果一个模块被很多地方都引用了,可以使用@Global将其设置为全局模块这样它exports的provider就可以直接注入使用:
@Catch、@UseFilters
filter是处理抛出的未捕获异常,通过@Catch来指定处理的异常:
然后通过
@UseFilters应用到handler上:
启动项目,刷新页面:
@UseGuards、@UseInterceptors、@UsePipes
这三种用法和上面的@UseFilters用法一样,需要先建立对应的provider,然后再使用对应的装饰器去调用。
@Param、@Query
@Param是获取路径中的参数,而@Query是获取url问号中的参数
@Post、@Body
在post请求中,@Body是获body请求体的参数:
一般使用dto的class来接受请求体里的参数:
使用postman发送一个请求,可以看到请求成功,且控制台也打印出了对应的参数:
@Put、@Delete、@Patch、@Options、@Head
分别接受put、delete、patch、options、head的请求
@SetMetadata
handler和class可以通过@SetMetadata指定metadata:
我们指定了一个class Metadata,一个method Metadata, 然后我们在guard或者interceptor中取出来:
刷新页面,查看打印的内容:
@Headers
通过装饰器获取某个请求头或者全部的请求头:
@Ip
可以通过这个,获取到当前请求的ip:
@Session
通过@Session可以获取到session对象:
要使用session,需要先安装一个express中间件:
npm install express-session
之后在main.ts中引入并启用:
指定加密的密钥,以及session生效的时间,然后刷新页面:
返回了set-cookie的响应头,设置了cookie,包含sid,也就是sessionid.
之后每次请求接口都会自动带上这个cookie:
同时,控制台也会根据我们的log打印这个session
之后我们就可以通过在session中存储信息,设置后其他接口在请求时也会带上这个存储的信息:
@HostParam
用于取域名部分的参数:
首先创建一个controller:
nest g co aaa --no-spec --flat
然后修改aaa.controller.ts指定生效的路径:
接着访问路由
127.0.0.1:3000,可以看到能够正常访问这个新的路径:
但是如果你使用
localhost:3000,这样的地址访问就不会访问到这个controller了,会发现只有host满足xx.0.0.1的时候才会路由到这个controller。
host里的参数就可以通过@HostParam取出来:
@Req 和 @Request
这两个装饰器是同一个东西,可以获取到request里的内容,当注入request对象后可以手动获取到请求中的参数:
@Res 和 @Response
这两个也是一个东西,只不过response有点特殊,在注入它的时候需要手动end,不然服务会一直卡着没有响应:
这样设计是为了避免你自己返回的响应和nest返回的响应冲突。
如果自己不想手动end,还可以通过向@Res中传入passthrough参数,来返回响应:
@HttpCode
可以通过这个来修改请求的状态码:
@Header
可以通过@Header来修改response header:
@Redirect
通过这个来指定路由重定向的url:
总结
- @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