egg学习笔记-1

9次阅读

共计 4535 个字符,预计需要花费 12 分钟才能阅读完成。

入门笔记
请按照官方文档初始化一个 simple 工程项目,按照如下步骤学习即可,如有不懂的请参考官方文档。
禁止 csrf 验证
根据如下步骤进行控制的创建,在执行 Post 操作的时候会出现 invalid csrf token 错误。需要禁止此特性。
创建路由
/**
* @param {Egg.Application} app – egg application
*/
module.exports = app => {
const {
router,
controller,
} = app;
router.get(‘/’, controller.home.index);
// 新建资源路由
router.resources(‘SystemUser’, ‘/system/user’, controller.system.user);
};
控制器 controller.system.user,对应的是 controller 目录下的 system 目录里面的 user.js 文件
创建对应的控制器
const Controller = require(‘egg’).Controller;

class SystemUserController extends Controller {
async index() {
const {
ctx,
} = this;
ctx.body = ‘hello ! this is SystemUserController’;
}
}
module.exports = SystemUserController;
访问地址:localhost:7001/system/user
创建可以提交数据的控制器方法
const Controller = require(‘egg’).Controller;

class SystemUserController extends Controller {
async index() {
const {
ctx,
} = this;
ctx.body = ‘hello ! this is SystemUserController’;
}

async create() {
const ctx = this.ctx;
const user = ctx.request.body;
ctx.body = user;
}
}

module.exports = SystemUserController;
POST 方法访问网址:localhost:7001/system/user 会提示 invalid csrf token 错误。
关闭 csrf 验证
// config\config.default.js
// 关闭 csrf 验证
config.security = {
csrf: {
enable: false,
},
};

开启验证
在上面的例子中,我们通过表单提交了任何数据,都会回显到界面上,如果是数据需要存储或者做其他业务处理,则需要对用户输入的数据进行验证。egg 提供了 egg-validate 插件进行表单验证
安装插件
cnpm install egg-validate –save
配置启用插件
/** @type Egg.EggPlugin */
module.exports = {
// had enabled by egg
// static: {
// enable: true,
// }
validate: {
enable: true,
package: ‘egg-validate’,
},

};
使用验证组件
首先创建一个规则,这里我们定义 username 是字符串而且是必须的,最大长度为 8 个字符。定义 password 为字符串且必须,最小长度为 6 个字符。ctx.validate(createRule, ctx.request.body); 通过上述语句进行参数检查更多规则请参考:https://github.com/node-modul…
const Controller = require(‘egg’).Controller;

// 定义本接口的请求参数的验证规则
const createRule = {
username: {
type: ‘string’,
required: true,
max: 8,
},
password: {
type: ‘string’,
required: true,
min: 6,
},
};

class SystemUserController extends Controller {
async index() {
const {
ctx,
} = this;
ctx.body = ‘hello ! this is SystemUserController’;
}

async create() {
const ctx = this.ctx;
// 验证输入参数是否符合预期格式
ctx.validate(createRule, ctx.request.body);
const user = ctx.request.body;
ctx.body = user;
}
}

module.exports = SystemUserController;
测试
使用 POSTMAN 提交任意字段,则会提示 Validation Failed (code: invalid_param) 如何查看具体错误信息呢。下面将定义统一错误处理的中间件进行错误处理。

统一错误处理中间件
在项目的 app 目录中创建 middleware 目录,此目录中可以创建中间件。
创建错误处理中间件
‘use strict’;
module.exports = () => {
return async function errorHandler(ctx, next) {
try {
await next();
} catch (err) {
// 控制台输出
console.error(‘MiddleWare errorHandler’, err);
// 所有的异常都在 app 上触发一个 error 事件,框架会记录一条错误日志
ctx.app.emit(‘error’, err, ctx);
// status 如果没有, 则统一为 500
const status = err.status || 500;
// 如果是 500 错误,且是生产环境,则统一显示“Internal Server Error”
const error = status === 500 && ctx.app.config.env === ‘prod’ ? ‘Internal Server Error’ : err;
// 改变上下文状态代码
ctx.status = status;
// 从 error 对象上读出各个属性,设置到响应中
ctx.body = {
error,
};
}
};
};
启用中间件
文件 configconfig.default.js 中
// add your middleware config here
config.middleware = [];
将其修改为包含你创建的中间件
// add your middleware config here
// errorHandler 统一错误处理
config.middleware = [‘errorHandler’];

// errorHandler 只在 /api 上生效
config.errorHandler = {
match: ‘/api’,
};
如上所示,可以设置错误处理中间件在什么 URL 上面起作用。这里我们使用 /api
测试路由
先使用原来的路由访问:localhost:7001/system/user 错误提示依旧变更路由:打开文件:approuter.js
// router.resources(‘SystemUser’, ‘/system/user’, controller.system.user);
router.resources(‘SystemUser’, ‘/api/v1/system/user’, controller.system.user);
再次访问:localhost:7001/api/v1/system/user 提示信息会变成:
{“error”:{“message”:”Validation Failed”,”code”:”invalid_param”,”errors”:[{“message”:”required”,”field”:”username”,”code”:”missing_field”},{“message”:”required”,”field”:”password”,”code”:”missing_field”}]}}

格式化接口返回的数据结构
在上面显示错误信息中,可以看到规范的 Json 数据,如果开发接口,我们就需要定义统一的数据结构,以便客户端进行解析。在 API 开发中,可以定义接口的标准返回格式。通过框架扩展方式定义返回数据格式是一个非常方便的方法。在 app 目录中创建 extend 目录,对 egg 的内置对象 Helper 进行扩展即可。
创建 Helper 扩展
文件:app/extend/helper.js
‘use strict’;

module.exports = {
/**
* 调用正常情况的返回数据封装
* @param {Object} ctx – context
* @param {*} msg – message
* @param {*} data – 数据
*/
success(ctx, msg, data) {
ctx.body = {
code: 0,
msg,
data,
};
ctx.status = 200;
},

/**
* 处理失败,处理传入的失败原因
* @param {*} ctx – context
* @param {Object} res – 返回的状态数据
*/

fail(ctx, res) {
ctx.body = {
code: res.code,
msg: res.msg,
data: res.data,
};
ctx.status = 200;
},
};
改造统一错误处理
// 从 error 对象上读出各个属性,设置到响应中
// ctx.body = {
// error,
// };
// 格式化返回错误信息
ctx.helper.fail(ctx, {
code: status,
msg: error.message,
data: error.errors,
});
测试
再次访问:localhost:7001/api/v1/system/user 提示信息会变成:
{
“code”: 422,
“msg”: “Validation Failed”,
“data”: [
{
“message”: “required”,
“field”: “username”,
“code”: “missing_field”
},
{
“message”: “required”,
“field”: “password”,
“code”: “missing_field”
}
]
}
将控制器 user 中的返回改为标准格式
async create() {
const ctx = this.ctx;
// 验证输入参数是否符合预期格式
ctx.validate(createRule, ctx.request.body);
const user = ctx.request.body;
// ctx.body = user;
this.ctx.helper.success(this.ctx, ‘ok’, user);
}
提交满足要求的数据,测试正确的返回数据 username testuser password 1234567890 提交后将返回标准的数据格式
{
“code”: 0,
“msg”: “ok”,
“data”: {
“username”: “testuser”,
“password”: “1234567890”
}
}

正文完
 0