资讯专栏INFORMATION COLUMN

egg学习笔记-1

wmui / 1446人阅读

摘要:入门笔记请按照官方文档初始化一个工程项目,按照如下步骤学习即可,如有不懂的请参考官方文档。需要禁止此特性。定义为字符串且必须,最小长度为个字符。下面将定义统一错误处理的中间件进行错误处理。在目录中创建目录,对的内置对象进行扩展即可。

入门笔记

请按照官方文档初始化一个simple工程项目,按照如下步骤学习即可,如有不懂的请参考官方文档。

禁止csrf验证

根据如下步骤进行控制的创建,在执行Post操作的时候会出现invalid csrf token错误。需要禁止此特性。

创建路由

</>复制代码

  1. /**
  2. * @param {Egg.Application} app - egg application
  3. */
  4. module.exports = app => {
  5. const {
  6. router,
  7. controller,
  8. } = app;
  9. router.get("/", controller.home.index);
  10. // 新建资源路由
  11. router.resources("SystemUser", "/system/user", controller.system.user);
  12. };

控制器controller.system.user,对应的是controller目录下的system目录里面的user.js文件

创建对应的控制器

</>复制代码

  1. const Controller = require("egg").Controller;
  2. class SystemUserController extends Controller {
  3. async index() {
  4. const {
  5. ctx,
  6. } = this;
  7. ctx.body = "hello ! this is SystemUserController";
  8. }
  9. }
  10. module.exports = SystemUserController;

访问地址:localhost:7001/system/user

创建可以提交数据的控制器方法

</>复制代码

  1. const Controller = require("egg").Controller;
  2. class SystemUserController extends Controller {
  3. async index() {
  4. const {
  5. ctx,
  6. } = this;
  7. ctx.body = "hello ! this is SystemUserController";
  8. }
  9. async create() {
  10. const ctx = this.ctx;
  11. const user = ctx.request.body;
  12. ctx.body = user;
  13. }
  14. }
  15. module.exports = SystemUserController;

POST方法访问网址:localhost:7001/system/user 会提示invalid csrf token错误。

关闭csrf验证

</>复制代码

  1. // configconfig.default.js
  2. // 关闭csrf验证
  3. config.security = {
  4. csrf: {
  5. enable: false,
  6. },
  7. };
开启验证

在上面的例子中,我们通过表单提交了任何数据,都会回显到界面上,如果是数据需要存储或者做其他业务处理,则需要对用户输入的数据进行验证。
egg提供了egg-validate插件进行表单验证

安装插件

</>复制代码

  1. cnpm install egg-validate --save
配置启用插件

</>复制代码

  1. /** @type Egg.EggPlugin */
  2. module.exports = {
  3. // had enabled by egg
  4. // static: {
  5. // enable: true,
  6. // }
  7. validate: {
  8. enable: true,
  9. package: "egg-validate",
  10. },
  11. };
使用验证组件

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

</>复制代码

  1. const Controller = require("egg").Controller;
  2. // 定义本接口的请求参数的验证规则
  3. const createRule = {
  4. username: {
  5. type: "string",
  6. required: true,
  7. max: 8,
  8. },
  9. password: {
  10. type: "string",
  11. required: true,
  12. min: 6,
  13. },
  14. };
  15. class SystemUserController extends Controller {
  16. async index() {
  17. const {
  18. ctx,
  19. } = this;
  20. ctx.body = "hello ! this is SystemUserController";
  21. }
  22. async create() {
  23. const ctx = this.ctx;
  24. // 验证输入参数是否符合预期格式
  25. ctx.validate(createRule, ctx.request.body);
  26. const user = ctx.request.body;
  27. ctx.body = user;
  28. }
  29. }
  30. module.exports = SystemUserController;
测试

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

统一错误处理中间件

在项目的app目录中创建middleware目录,此目录中可以创建中间件。

创建错误处理中间件

</>复制代码

  1. "use strict";
  2. module.exports = () => {
  3. return async function errorHandler(ctx, next) {
  4. try {
  5. await next();
  6. } catch (err) {
  7. // 控制台输出
  8. console.error("MiddleWare errorHandler", err);
  9. // 所有的异常都在 app 上触发一个 error 事件,框架会记录一条错误日志
  10. ctx.app.emit("error", err, ctx);
  11. // status 如果没有,则统一为500
  12. const status = err.status || 500;
  13. // 如果是500错误,且是生产环境,则统一显示“Internal Server Error”
  14. const error = status === 500 && ctx.app.config.env === "prod" ? "Internal Server Error" : err;
  15. // 改变上下文状态代码
  16. ctx.status = status;
  17. // 从 error 对象上读出各个属性,设置到响应中
  18. ctx.body = {
  19. error,
  20. };
  21. }
  22. };
  23. };
启用中间件

文件configconfig.default.js中

</>复制代码

  1. // add your middleware config here
  2. config.middleware = [];

将其修改为包含你创建的中间件

</>复制代码

  1. // add your middleware config here
  2. // errorHandler 统一错误处理
  3. config.middleware = [ "errorHandler" ];
  4. // errorHandler 只在/api上生效
  5. config.errorHandler = {
  6. match: "/api",
  7. };

如上所示,可以设置错误处理中间件在什么URL上面起作用。这里我们使用/api

测试路由

先使用原来的路由访问:localhost:7001/system/user
错误提示依旧
变更路由:打开文件:approuter.js

</>复制代码

  1. // router.resources("SystemUser", "/system/user", controller.system.user);
  2. router.resources("SystemUser", "/api/v1/system/user", controller.system.user);

再次访问:localhost:7001/api/v1/system/user
提示信息会变成:

</>复制代码

  1. {"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

</>复制代码

  1. "use strict";
  2. module.exports = {
  3. /**
  4. * 调用正常情况的返回数据封装
  5. * @param {Object} ctx - context
  6. * @param {*} msg - message
  7. * @param {*} data - 数据
  8. */
  9. success(ctx, msg, data) {
  10. ctx.body = {
  11. code: 0,
  12. msg,
  13. data,
  14. };
  15. ctx.status = 200;
  16. },
  17. /**
  18. * 处理失败,处理传入的失败原因
  19. * @param {*} ctx - context
  20. * @param {Object} res - 返回的状态数据
  21. */
  22. fail(ctx, res) {
  23. ctx.body = {
  24. code: res.code,
  25. msg: res.msg,
  26. data: res.data,
  27. };
  28. ctx.status = 200;
  29. },
  30. };
改造统一错误处理

</>复制代码

  1. // 从 error 对象上读出各个属性,设置到响应中
  2. // ctx.body = {
  3. // error,
  4. // };
  5. // 格式化返回错误信息
  6. ctx.helper.fail(ctx, {
  7. code: status,
  8. msg: error.message,
  9. data: error.errors,
  10. });
测试

再次访问:localhost:7001/api/v1/system/user
提示信息会变成:

</>复制代码

  1. {
  2. "code": 422,
  3. "msg": "Validation Failed",
  4. "data": [
  5. {
  6. "message": "required",
  7. "field": "username",
  8. "code": "missing_field"
  9. },
  10. {
  11. "message": "required",
  12. "field": "password",
  13. "code": "missing_field"
  14. }
  15. ]
  16. }
将控制器user中的返回改为标准格式

</>复制代码

  1. async create() {
  2. const ctx = this.ctx;
  3. // 验证输入参数是否符合预期格式
  4. ctx.validate(createRule, ctx.request.body);
  5. const user = ctx.request.body;
  6. // ctx.body = user;
  7. this.ctx.helper.success(this.ctx, "ok", user);
  8. }

提交满足要求的数据,测试正确的返回数据
username testuser
password 1234567890
提交后将返回标准的数据格式

</>复制代码

  1. {
  2. "code": 0,
  3. "msg": "ok",
  4. "data": {
  5. "username": "testuser",
  6. "password": "1234567890"
  7. }
  8. }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102143.html

相关文章

  • 《JSON必知必会》学习笔记(一)

    摘要:基于对象字面量,但是独立于任何编程语言,真正重要的是表示法本身,所以在学习之前不必先学习。键必须是字符串,值可以是合法的数据类型字符串数字对象数组布尔值或。布尔类型中的布尔值仅可使用小写形式或,其他任何写法都会报错。 什么是JSON JSON全称是Javascript Object Notation(对象表示法),是一种在不同平台间传递数据的文本格式(数据交换格式)。常见的数据交换格式...

    rickchen 评论0 收藏0
  • 《JSON必知必会》学习笔记(一)

    摘要:基于对象字面量,但是独立于任何编程语言,真正重要的是表示法本身,所以在学习之前不必先学习。键必须是字符串,值可以是合法的数据类型字符串数字对象数组布尔值或。布尔类型中的布尔值仅可使用小写形式或,其他任何写法都会报错。 什么是JSON JSON全称是Javascript Object Notation(对象表示法),是一种在不同平台间传递数据的文本格式(数据交换格式)。常见的数据交换格式...

    imccl 评论0 收藏0
  • head first python(第二章)–学习笔记

    摘要:第二章学习流程图函数转换为模块函数转换为模块后,就可以灵活的使用模块,方便代码分类,避免代码堆积在一个文件上。使用命令打包代码,生成发布包打包后会生成目录和文件发布后会多了目录和文件,这个是发布的生成的包和相关配置文件。 head first python(第二章)--学习流程图showImg(http://source1.godblessyuan.com/blog_head_firs...

    import. 评论0 收藏0
  • Egg学习_Setp1_初始化项目添加数据库

    摘要:前言本系列文章是学习过程的一个记录初步目标是写一个个人博客会尽可能多使用中提供的各种功能本文全部使用请确保版本足够支持文中有不正确地方请指正地址文档初始化项目使用脚手架初始化项目选择初始化项目的类型项目目录结构自定义启动时 前言 本系列文章是Egg学习过程的一个记录,初步目标是写一个个人博客,会尽可能多使用Egg中提供的各种功能.本文全部使用 async 请确保Node版本足够支持.文...

    Karrdy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<