一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情。
前言
egg.js的三层架构
- 信息资源层:就是action,或者servlet,用来处理上下游数据结构
- 业务逻辑层一般应用中会有一层service抽象,实现核心业务逻辑,事务控制也在这一层实现
- 数据访问层也是dao层,重点负责数据库访问,完成持久化功能
初体验
- 创建项目
npm i egg-init -g egg-init egg --type-simple cd egg-example npm i 先安装egg随后创建项目
- 项目结构
- Public
- Router->Controller->Service->Model
- Schedule 分别是公共的html静态文件,路由Model,Schedule任务系统功能文件
- 路由创建 在Routerjs创建
router.get('/user', controller.user.index);
- 创建控制器
const Controller = require('egg').Controller;
class UserController extends Controller {
...
}
module.exports = UserController;
约定优先于配置,避免减少开发者做决定的数量,不失灵活而且简单方便
- 创建一个新服务并使用 和创建控制器方式类似,一个是Controller一个是Service
const Service = require('egg').Service;
class UserController extends Service{}
// 使用服务
async index() {
const { ctx } = this;
ctx.body = await ctx.service.user.getAll();
}
- 创建模型层:以mysql+sequelize示例数据持久化
- 安装
npm i --save egg-sequelize myzql2
- 在config/plugin.js中引入该插件
sequelize: {
enable: true,
package: 'egg-sequelize',
}
}
- 在config/config.default.js中编写该配置
sequelize: {
dialect: "mysql",
host: "127.0.0.1",
port: 3306,
username: "root",
password: "example",
database: "xx"
}
实现分层架构
这样做的目的是创建约定大于配置、开发效率高,可维护性强的项目架构
- 路由处理
- 规范:
所有路由,都要方在routers文件夹中;若导出路由对象,使用
动词+空格+路径作为Key,值是操作方法;若导出函数,则函数返回第二条约定格式的对象; - 路由定义 创建的indexjs没有前缀,比如:
module.exports = {
'get /':async ctx=>{
ctx.body = '⾸⻚'
},
}
- 新建页面比如详情页要加上前缀
module.exports = {
"get /userinfo": async ctx => {
ctx.body = "⽤户详情";
},
};
定时任务
咱们使用Node-schedule来管理定时任务
- 安装
npm i node-schedule --save - 约定:schedule目录,来存放定时任务,使用crontab格式来启动定时任务
module.exports = {
interval:'*/3 * * * * *',
handler(){
console.log('三秒执⾏⼀次'+ new Date())
}
}
定时格式是符合linux的crobtab
interval中的六个字符从左到右分别代表:秒、分、时、日、月、星期几; * 标识通配符匹配任意,比如当秒是 * 时标识任意秒数都触发,其他的也是这样
- 读取控制器目录
load("schedule", (filename, scheduleConfig) => {
schedule.scheduleJob(scheduleConfig.interval,
scheduleConfig.handler);
})
module.exports = {
initRouter, initController,
initService, initSchedule
};
通过约定文件夹的形式,相当于时开始了MVC的模式开发!