基本使用
通常情况下,在 nest.js 的 swagger 页面文档中的响应数据文档默认如下
此时要为这个控制器添加响应数据文档的话,只需要先声明 数据的类型,然后通过@ApiResponse 装饰器添加到该控制器上即可,举例说明
todo.entity.tstypescript
@Entity('todo')
export class TodoEntity {
@Column()
@ApiProperty({ description: 'todo' })
value: string
@ApiProperty({ description: 'todo' })
@Column({ default: false })
status: boolean
}
todo.controller.tstypescript
@Get()
@ApiOperation({ summary: '获取Todo详情' })
@ApiResponse({ type: [TodoEntity] })
async list(): Promise<TodoEntity[]> {
return this.todoService.list();
}
@Get(':id')
@ApiOperation({ summary: '获取Todo详情' })
@ApiResponse({ type: TodoEntity })
async info(@IdParam() id: number): Promise<TodoEntity> {
return this.todoService.detail(id);
}
此时对应的文档数据如下显示
如果你想要自定义返回的数据,而不是用 entity 对象的话,可以按照如下定义
todo.model.tstypescript
export class Todo {
@ApiProperty({ description: 'todo' })
value: string
@ApiProperty({ description: 'todo' })
status: boolean
}
然后将 @ApiResponse({ type: TodoEntity })
中的 TodoEntity
替换 Todo
即可。
自定义返回数据
然而通常情况下,都会对返回数据进行一层包装,如
{
"data": [
{
"name": "string"
}
],
"code": 200,
"message": "success"
}
其中 data 数据就是原始数据。要实现这种数据结构字段,首先定义一个自定义类用于包装,如
res.model.tstypescript
export class ResOp<T = any> {
@ApiProperty({ type: 'object' })
data?: T
@ApiProperty({ type: 'number', default: 200 })
code: number
@ApiProperty({ type: 'string', default: 'success' })
message: string
constructor(code: number, data: T, message = 'success') {
this.code = code
this.data = data
this.message = message
}
}
接着在定义一个拦截器,将 data 数据用 ResOp 包装,如下拦截器代码如下
transform.interceptor.tstypescript
export class TransformInterceptor implements NestInterceptor {
constructor(private readonly reflector: Reflector) {}
intercept(context: ExecutionContext, next: CallHandler<any>): Observable<any> {
return next.handle().pipe(
map(data => {
const response = context.switchToHttp().getResponse<FastifyReply>()
response.header('Content-Type', 'application/json; charset=utf-8')
return new ResOp(HttpStatus.OK, data ?? null)
}),
)
}
}
此时返回的数据都会转换为 { "data": { }, "code": 200, "message": "success" }
的形式,这部分不为就本文重点,就不赘述了。
回到 Swagger 文档中,只需将 @ApiResponse({ type: TodoEntity })
改写成 @ApiResponse({ type: ResOp<TodoEntity> })
,就可以实现下图需求。