Midwayjs 之 编写baseController和配置swagger
介绍
本来是只想根据controller配置相关的swagger,但是在这个过程中,发现controller需要配置返回格式、异常处理等内容。本篇文章,继续以用户实体为基础编写Controller相关内容。
编写Controller
Controller统一的返回格式
根据路由和控制器,能够很快的编写一个Controller。但是在实际的开发过程中,直接用下面的代码:
会发现,每个接口都手动编写返回体?前端开发追求的是优雅,所以这是不可接受的。其次,异常如何处理?
为此编写一个返回对象的基类:
export const DEFAULT_SUCCESS_CODE = 200;
export const DEFAULT_ERROR_CODE = 900;
export interface IResult<T = any> {
data?: T;
code?: number;
message?: string;
}
export const Result = {
success<T>(option: IResult<T> = {}): IResult<T> {
const {
data = null,
code = DEFAULT_SUCCESS_CODE,
message = 'success',
} = option;
return {
code,
data,
message,
};
},
error(option: IResult = {}): IResult {
const {
data = null,
code = DEFAULT_ERROR_CODE,
message = 'error',
} = option;
return {
code,
data,
message,
};
},
};
然后再编写一个Controller的基础类型,代码如下:
import { Inject } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { IResult, Result } from '../utils/result';
export abstract class BaseController {
@Inject()
ctx: Context;
success<T>(data?: T, option: IResult<T> = {}): IResult<T> {
return Result.success<T>({ data, ...option });
}
error(message?, option: IResult = {}) {
return Result.error({ message, ...option });
}
}
然后修改UserController,相关的代码如下:
这么看,代码的返回就很完美了。
如何异常处理
根据异常处理,编写一个filter,实现统一的异常处理。根据上一章节的描述,把异常的处理处理编写如下:
import { Catch } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { Result } from '../utils/result';
@Catch()
export class ExceptionFilter {
async catch(err, ctx: Context) {
ctx.logger.error(err);
return Result.error({
code: err.status ?? 500,
message: err.message,
});
}
}
然后,添加配置。
配置controller的Swagger
返回单体对象【CommonItemResponse】
在Swagger的【泛型返回数据】中,详细描述了返回单体泛型的配置,样例代码如下:
// 对象的Swagger类型
type ResItem<T> = {
code: number;
message: string;
data: T;
};
export function SuccessItemWrapper<T>(ResourceCls: Type<T>): Type<ResItem<T>> {
class CommonItemResponse {
@ApiProperty({ description: '状态码', default: 200 })
code: number;
@ApiProperty({ description: '消息' })
message: string;
@ApiProperty({
type: ResourceCls,
})
data: T;
}
return CommonItemResponse;
}
使用的代码如下:
效果如下:
返回分页对象【CommonPageResponse】
在Swagger的【泛型返回数据】中,虽然描述了返回单泛型对象,但是对于分页的对象如何配置没有描述,研究了下后,代码如下::
// 分页的Swagger类型
type ResPage<T> = {
code: number;
message: string;
data: Type<T>[];
pagination: Pagination;
};
export function SuccessPageWrapper<T>(
ResourceCls: Type<T>,
PaginationCls: Type<Pagination>
): Type<ResPage<T>> {
class CommonPageResponse {
@ApiProperty({ description: '状态码', default: 200 })
code: number;
@ApiProperty({ description: '消息' })
message: string;
@ApiProperty({
type: ResourceCls,
})
data: Type<T>[];
@ApiProperty({
type: PaginationCls,
})
pagination: Pagination;
}
return CommonPageResponse;
}
使用的代码如下:
效果如下:
返回通用对象【CommonResponse】
这个就简单了,直接上代码:
// 通用对象
type Res = {
code: number;
message: string;
data: object;
};
export function SuccessWrapper(): Type<Res> {
class CommonResponse {
@ApiProperty({ description: '状态码', default: 200 })
code: number;
@ApiProperty({ description: '消息' })
message: string;
@ApiProperty({
type: Object,
})
data: object;
}
return CommonResponse;
}
使用的代码如下:
效果如下:
总结和思考
思考
- Swagger
请求接口的入参描述,整体根据官网来进行配置,基本是没有啥问题的。但是接口的返回对象进行配置时,官网就显的比较简单,需要开发人员进行研究。
- Controller
如何优雅的进行返回内容的格式定义和错误定义。这是一个开发框架最基本的思考。
总结
完成本章节的配置后,整体的MVC框架,最基础的内容就算可以了。能够提供给前端做开发处理了。因为swagger有了,返回内容统一了。
转载自:https://juejin.cn/post/7377275977414688795