课程名称:web前端架构师
课程章节:第15周 第八章 用户系统的设计与实现
主讲老师:张轩
课程内容: 接口参数验证功能和错误信息处理
使用egg-validate 验证参数
之前的开发没有对用户的参数进行校验 ,这样做明显很不合理
egg.js 官方提供了 egg-validate 插件用来进行参数校验
安装 egg-validate
npm i egg-validate
将插件添加到 config 文件中
// config/plugin.js
const plugin: EggPlugin = {
...
validate: {
enable: true,
package: 'egg-validate',
},
...
};
export default plugin;
validate 内部使用了 parameter 这个库来完成验证, 文档地址 https://github.com/node-modules/parameter 。它是专门为验证参数所建立的,贡献者大部分都是 egg.js 的作者。
如何使用可以查看文档
在 controller 中使用 egg-validate
export default class UserController extends Controller {
public async createByEmail() {
const { ctx, service, app } = this;
const errors = app.validator.validate({
username: 'email',
password: {
type: 'password',
min: 8,
},
}, ctx.request.body);
if (errors.length) {
// 调用错误信息统一处理
return ctx.helper.error({ ctx, errno: 1001, msg: '参数错误' });
}
const res = await service.user.createByEmail(ctx.request.body);
return ctx.helper.success
}
}
这样参数校验就完成了
规范错误信息
之前我们已经处理了关于成功信息的处理,这里回顾一下。我们在 app/extend/helper.ts
中是实现了请求成功的统一处理
// app/extend/helper.ts
import { Context } from 'egg';
interface RespType{
ctx: Context
res?: any
msg?: string
}
export default {
success({ ctx, res, msg }: RespType) {
ctx.body = {
errno: 0,
data: res ? res : null,
msg: msg ? msg : 'success',
};
ctx.status = 200;
},
在 controller 中可以直接调用 ctx.helper.success({ ctx, res });
就可以将成功数据返回给用户
在 app/extend/helper.ts
中实现错误信息的统一处理, 这样 controller 就可以统一调用错误处理的方法了
interface ErrorRespType{
ctx: Context
errno: number
msg?: string
}
export default {
error({ ctx, errno, msg }: ErrorRespType) {
ctx.body = {
errno,
msg: msg ? msg : 'err',
};
ctx.status = 200;
},
};
错误码的设计原则
统一格式:A-BB-CCC
A. 错误级别,如 1 代表系统级错误,2 代表服务级错误
B. 项目或模块名称,一般公司不会超过 99 个项目,这里使用 01 代表用户模块。
C. 具体错误编号,自增即可,一个项目 999 种错误应该够用
创建用户的错误码就是 101001
统一错误码处理
创建用户失败后,需要给用户返回具体的错误信息,例如 username 字段没填等
创建用户失败的错误信息
export const errMsg = {
createUserValidateFail: {
errno: 101001,
message: '创建用户验证失败',
},
};
统一错误信息处理,对之前的代码再进行改造
interface ErrorRespType{
ctx: Context
// errType 就可以拿到 errMsg 的所有key
errType: keyof(typeof errMsg)
err?: any
}
export default {
error({ ctx, errType, err }: ErrorRespType) {
const { msg, errno } = errMsg[errType];
ctx.body = {
errno,
msg: msg ? msg : 'err',
// err 存在就会返回 err 字段 ,否则不会
...(err && { err }),
};
ctx.status = 200;
},
};
controller 进行调用,我们在写 errType 时也会给我们有提示信息,很方便
const errors = app.validator.validate({
username: 'email',
password: {
type: 'password',
min: 8,
},
}, ctx.request.body);
if (errors && errors.length) {
return ctx.helper.error({ ctx, errType: 'createUserValidateFail', err: errors });
}