前言
国有国法,家有家规,当我们一群人共同在做一件事情时,如果不加以约束,每个人做事的方式就会按照自己喜爱的方式进行,凌乱不堪,让后来加入者需要更多的时间,熟悉前人所做事情,然而所做的事情也是凌乱不堪的,我们为何不加以约束。
eggjs是一个nodejs框架,继承与koa框架,egg.js为企业级框架和应用而生,所奉行的宗旨约定优于配置,按照一套统一的约定进行开发。
安装
环境要求nodejs环境最低要求8.x
安装脚手架$ mkdir egg-example && cd egg-example
$ npm init egg --type=simple
$ npm i复制代码
官网也有逐步搭建过程
目录结构约束egg-project
├── package.json
├── app.js (可选)
├── agent.js (可选)
├── app
| ├── router.js
│ ├── controller
│ | └── home.js
│ ├── service (可选)
│ | └── user.js
│ ├── middleware (可选)
│ | └── response_time.js
│ ├── schedule (可选)
│ | └── my_task.js
│ ├── public (可选)
│ | └── reset.css
│ ├── view (可选)
│ | └── home.tpl
│ └── extend (可选)
│ ├── helper.js (可选)
│ ├── request.js (可选)
│ ├── response.js (可选)
│ ├── context.js (可选)
│ ├── application.js (可选)
│ └── agent.js (可选)
├── config
| ├── plugin.js
| ├── config.default.js
│ ├── config.prod.js
| ├── config.test.js (可选)
| ├── config.local.js (可选)
| └── config.unittest.js (可选)
└── test
├── middleware
| └── response_time.test.js
└── controller
└── home.test.js复制代码
内置基础对象
eggjs框架从koa框架继承了四个对象(Application,Context,Request,Response),框架本身也扩展了一些对象(Controller,Service,helper,Config,Looger)
Application对象
Application是一个全局对象,只会实例化一个,Application对象继承koa.Application对象,在上面可以挂载一些全局的方法和属性
简单使用
我们用业务来表述技术的使用,例如我们现在有一个记账的业务。
router
首先我们要有api接口,当我们有多个api接口时,怎么做区分? 使用router路由进行分发请求。我们在app文件下面创建router.js文件,通过从Application对象中结构出router来使用路由的功能// router.js module.exports = app => { const { router, controller, jwt } = app; // 登陆接口
router.get('/keeping/api/v1/login', controller.login.login); // 查询用户
router.get('/keeping/api/v1/getUser', jwt, controller.user.selectUser);
};// 第一个参数是访问的地址,第二个参数告诉我们匹配成功后分发到相应的controller上,复制代码
costroller
当我们分发到相应的controller上进行解析用户的输入,处理后返回相应的结果。
在app下新建controller.js文件,拿到用户的输入值,我们会把业务逻辑做一个拆分,会调用相应业务逻辑,就是我们所说的service// controller.jsconst { Controller } = require('egg');class LoginController extends Controller { // 登陆api
async login() {const { ctx, app } = this; // 拿到用户的输入值const query = ctx.query;// 调用service服务const loginInfo = await ctx.service.login.login(query); // 生成token const token = app.jwt.sign({ user: loginInfo,
}, app.config.jwt.secret);const openid = loginInfo.openid;// 返回值ctx.body = {
openid, token: `Bearer ${token}`, success: '登陆成功', code: 200,
};
} // 查询用户
async selectUser() {const { ctx } = this;const query = ctx.query;console.log(query, '........query======');const user = await ctx.service.user.selectUser(query);if (user) { this.ctx.body = {success: true,message: '查询成功',status: 200,data: user,
};
} else { this.ctx.body = {success: false,message: '查询失败',status: 40023,
};
}
}
}module.exports = LoginController;复制代码
service
controller调用service业务逻辑,我们在app文件下新建service文件,在service文件下编写抽离出来的业务逻辑的封装,把业务逻辑抽离出来使我们的controller更加的简洁,保持业务的独立性,抽离出来的service可以被多个controller使用。// service.jsconst { Service } = require('egg');class LoginService extends Service { // 登陆
async login(data) {const { app, ctx } = this; // 这里我通过在config下面配置常量,通过引用调用,此接口是登陆接口const { appid, secret } = app.config.weapp;const result = await ctx.curl(`https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${data.code}&grant_type=authorization_code`, { dataType: 'json' });const aa = await ctx.service.user.selectUser(result.data);if (!aa) { await ctx.service.user.addUser({ openid: result.data.openid });
}return result.data;
}
// 查询用户
async selectUser(openid) {const { app } = this;const userTable = app.config.sqlTable.user;const user = await app.mysql.get(userTable, openid);return user;
}
}module.exports = LoginService;复制代码
config
当我们需要使用数据库时,我们就要使用plugin,例如我们使用mysql数据库,需要安装egg-mysql,安装后在config/plugin.js中声明:// 配置mysql
mysql: {enable: true,package: 'egg-mysql',
},复制代码
然后在config/config.default.js中配置数据库连接的相关配置// 配置mysql
config.mysql = {// 单数据库信息配置client: { host: 'localhost', //主机名 port: '3306',//端口号 user: 'root',// 数据库用户名 password: '123456', // 数据库密码 database: 'xilou', //数据库表名},// 是否加载到 app 上,默认开启app: true,agent: false,
};复制代码
后续会配置一些解决跨域的egg-cors插件,生成token的egg-jwt插件,配置如mysql一样,这样一个流程就完成了,我们使用postman进行请求下,因为数据库我已经配置好,现在进行查询用户的一个请求,数据库里面的数据是我已经插入进去的,查询用户如下
中间件
我们可以自己编写中间件,放在app/middleware文件下面,在config.default.js下面配置中间件
总结
上面阐述了eggjs的基本使用。
eggjs对开发团队进行约定,有利于团队开发,减少开发人员的学习成本,开箱即用。eggjs使用路由分发请求,具体执行的动作
使用controller负责解析用户的输入,处理返回相应的结果
使用service处理相应的业务逻辑
因为nodejs是异步,采用async来进行处理
其他的无非使用插件来增强功能,例如连接数据库,要么使用中间件来增强功能,通过挂载在Application下使用
如果有哪些言辞不正之处,错误之处,欢迎指正,后续会进行更改