四、响应和Next
在上一节,我们说了请求参数的装饰器,这一节我们看下响应@Res和@Next
前置知识
与请求类似,响应也有两个相同功能的装饰器@Response和@Res,Res是 Response的别名。
两者直接公开底层原生平台的response对象接口(当然在我们这里就是express.Response,但是Nest本身还支持express之外的其他库作为底层)。如果注入了Res/Response,那就需要自己管理响应了(比如res.send(...)),否则该服务会被挂起,不会响应。
当然这不是绝对的,如果你只是想注入Response用来设置一些headers/cookie等内容,并不想自己来负责响应,那么可以通过@Response({passthrough:true})来实现,在方法中正常return要返回的内容即可
为什么会有
@Res是@Response的别名,@Req是@Request的别名呢?因为
@Request装饰的参数会传递express的Request类型,@Response同理,所以如果这样写:
1
2
3
4 import { Request } from '@nestjs/common'
import type { Request } from 'express'
()
getHello( request: Request) {}他们都叫
Request,名字会重复,所以在用的时候要么得起别名import type { Request as ExpressRequest } from 'express',要么直接只用@Req来替代@Request会是一个好办法。
@Res
我们先添加了两个新的路由,分别是自己控制响应和自动返回响应内容:
1 | // users.controller.ts |
第一步我们先实现@Res/@Response两个装饰器,跟其他的并无什么差异:
1 | // @nestjs/common/param.decorator.ts |
在NestApplication中我们依然要添加一个新的case,这里返回express的原生Response对象就好了:
1 | // @nestjs/core/nest-application.ts |
在之前我们的代码中,我们在注册路由时,在处理程序中执行对应方法获取到响应值并将其返回到了客户端,但是现在我们需要判断是否要自动将响应值返回,所以我们在NestApplication中加了一个新的方法用于判断
1 | // @nestjs/core/nest-application.ts |
在NestApplication中的init方法里,我们在注册路由的时候就需要做一些判断了:
1 | // @nestjs/core/nest-application.ts |
@Next
说完Response,还要提到一个就是@Next,我们知道路由处理程序有三个参数req, res, next,前边的请求和响应已经说完了,这里要说一下next,在express中next和koa中的概念并不相同,这里并不是一个洋葱模型,而是如果你不执行next就不会执行后边的中间件了,所以当注入了@Next,那么也需要堵塞程序的运行
添加一个新的路由:
1 | // users.controller.ts |
定义@Next装饰器
1 | // @nestjs/common/param.decorator.ts |
在NestApplication中添加一个新的Case,就是传递next:
1 | // @nestjs/core/nest-application.ts |
在我们的判断是否自动返回的方法中,就需要添加一个新的判断条件了,ifAutoResponse方法修改为:
1 | // @nestjs/core/nest-application.ts |
这样就可以正常运行了。
到此,我们对于Response的处理就结束了,主要还是在NestApplication中的一些修改。