介绍
Egg.js 官网
Egg.js 是《阿里旗下产品》基于 Node.js 和 Koa 是一个 Nodejs 的企业级应用开发框架。 可以帮助发团队和开发人员降低开发和维护成本。
Express 和 Koa 是 Node.js 社区广泛使用的框架,简单且扩展性强,非常适合做个人项 目。但框架本身缺少约定,标准的 MVC 模型会有各种千奇百怪的写法。Egg 按照约定进行 开发,奉行『约定优于配置』,团队协作成本低。
Egg.js 基于 Es6、Es7 以及 Typescript、Koa2 使得 Nodejs 具有更规范的开发模式、更低 的学习成本、更优雅的代码、更少的开发成本、更少的维护成本。为企业级框架而生。
特性
- 提供基于 Egg 定制上层框架的能力
- 高度可扩展的插件机制
- 内置多进程管理
- 基于 Koa 开发,性能优异
- 框架稳定,测试覆盖率高
- 渐进式开发
Egg 快速入门、搭建环境、创建项目
环境准备
操作系统:支持 macOS,Linux,Windows
运行环境:Nodejs 建议选择 LTS 版本,Nodejs 最低要求 8.x。
安装 egg 脚手架以及使用 egg-init 创建项目
我们推荐直接使用脚手架,只需几条简单指令,即可快速生成项目:
1 2 3 4
| npm i egg-init -g egg-init egg-example --type=simple cd egg-example npm i
|
启动项目:
目录介绍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| |-- .idea idea配置文件 |-- app 项目开发目录* |-- router.js |-- controller 控制器 |-- service(可选) 数据模型 |-- middleware(可选) |-- public(可选) 静态资源目录 |-- reset.css |-- view(可选) 视图 |-- config 项目配置文件* |-- plugin.js |-- config.default.js |-- config.prod.js |-- logs 日志文件* |-- node_modules |-- run 项目运行配置文件 |-- test 测试文件 |-- package.json 项目配置文件 管理项目模块等元数据* |-- appveyor.yml |-- jsconfig.json |-- README.md |-- typings |-- yarn.lock
|
app 的类型是 Egg.Application,是全局应用对象,在每个项目中只会实例化一次,也就是说 egg.js 默认把 router,controller 集成好了。
controller 里放置个个业务模块;
egg.js 使用规范:文件名小写,类名首字母大写并使用驼峰命名;
egg.js 框架中使用同步编程模式=> async…await;
ctx 每次用户在使用时,框架就会实例化的一个 Egg.content 上下文,content 用来存放用户请求的一些信息;
路由
Router 主要用来描述请求 URL 和具体承担执行动作的 Controller 的对应关系, 框架约定了 app/router.js 文件用于统一所有路由规则。
通过统一的配置,我们可以避免路由规则逻辑散落在多个地方,从而出现未知的冲突,集中在一起我们可以更方便的来查看全局的路由规则。
定义 Router
- app/router.js 里面定义 URL 路由规则
1 2 3 4 5 6 7 8 9 10
| "use strict";
module.exports = app => { const { router, controller } = app;
router.get("/", controller.home.index); };
|
控制器
Controller 负责解析用户的输入,处理后返回相应的结果。框架推荐 Controller 层主要对用户的请求参数进行处理(校验、转换),然后调用对应的 service 方法处理业务,得到业务结果后封装并返回:
- 获取用户通过 HTTP 传递过来的请求参数。
- 校验、组装参数。
- 调用 Service 进行业务处理,必要时处理转换 Service 的返回结果,让它适应用户的需求。
- 通过 HTTP 将结果响应给用户。
传参
GET、POST、PUT、DELETE的区别
1、POST 创建
2、DELETE 删除
3、PUT 更新
4、GET 查看
get 请求两种传参
put 和 delete 请求传参格式与 get 请求一致
- params
路由配置
1
| router.get("/news/detail/:id", controller.news.detail);
|
获取方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class NewsController extends Controller { detail() { const { ctx } = this;
var params = ctx.params || {}; console.log(params);
ctx.body = { code: 0, data: { params }, msg: "请求成功" }; } }
|
- query
路由配置
1
| router.get("/news/updateId", controller.news.updateId);
|
获取方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class NewsController extends Controller { async updateId() { const { ctx } = this;
const data = await ctx.query;
ctx.body = { code: 0, data, msg: "修改成功" }; } }
|
post 请求传参
路由配置
1
| router.post("/news/add", controller.news.add);
|
获取方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class NewsController extends Controller { async add() { const { ctx } = this;
const data = await ctx.request.body;
ctx.body = { code: 0, data, msg: "添加成功" }; } }
|
mysql
- 安装对应的插件 egg-mysql :
- 开启插件:
1 2 3 4 5 6 7 8 9
| "use strict";
module.exports = { mysql: { enable: true, package: "egg-mysql" } };
|
- 单数据源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
config.mysql = { client: { host: "0.0.0.0", port: "0000", user: "username", password: "password", database: "dbname" }, app: true, agent: false };
|
sequelize
- 安装
1
| npm install --save egg-sequelize mysql2
|
- 开启插件:
1 2 3 4 5 6 7 8 9
| "use strict";
module.exports = { sequelize: { enable: true, package: "egg-sequelize" } };
|
- 编写 sequelize 配置
1 2 3 4 5 6 7 8 9 10 11
|
config.sequelize = { Sequelize: require("sequelize"), dialect: "mysql", database: "test_ry", host: "47.94.214.227", port: "3306", username: "root", password: "123456" };
|
service
- router.js
1 2 3 4 5
| module.exports = app => { const { router, controller } = app;
};
|
- /service/article.js
1 2 3 4 5 6 7 8 9
| "use strict";
const Service = require("egg").Service;
class ArticleService extends Service { }
module.exports = ArticleService;
|
- /controller/article.js
1 2 3 4 5 6 7 8 9 10
| "use strict";
const Controller = require("egg").Controller; const moment = require("moment");
class ArticleController extends Controller { }
module.exports = ArticleController;
|
增
- router.js
1
| router.post("/article/create", controller.article.create);
|
- /service/article.js
1 2 3 4 5 6 7 8 9 10
| async create(params) { const { app } = this; try { const result = app.mysql.insert("newsList", params); return result; } catch (error) { console.log(error); return null; } }
|
- /controller/article.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| async create() { const { ctx, service } = this;
const data = { ...ctx.request.body, create_time: moment().format("YYYY-MM-DD HH:mm:ss") };
const result = await service.article.create(data);
if (result) { ctx.body = { status: 200, data: result }; } else { ctx.body = { status: 500, msg: "发布文章失败" }; } }
|
删
- router.js
1
| router.delete("/article/delete/:id", controller.article.delete);
|
- /service/article.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| async delete(id) { if (!id) { console.log("id必须传递"); return null; }
try { const result = await this.app.mysql.delete("newsList", { id }); return result; } catch (error) { console.log(error); return null; } }
|
- /controller/article.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| async delete() { const { ctx, service } = this;
const result = await service.article.delete(ctx.params.id);
if (result) { ctx.body = { status: 200, data: result }; } else { ctx.body = { status: 500, msg: "删除文章失败" }; } }
|
查
- router.js
1 2
| router.get("/article/lists", controller.article.lists); router.get("/article/detail/:id", controller.article.detail);
|
- /service/article.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| async lists() { const { app } = this;
try { const result = await app.mysql.select("newsList", { orders: [["id", "desc"]], limit: 2 }); return result; } catch (error) { console.log(error); return null; } }
async detail(id) { if (!id) { console.log("id必须传递"); return null; }
try { const result = await this.app.mysql.get("newsList", { id }); return result; } catch (error) { console.log(error); return null; } }
|
- /controller/article.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| async lists() { const { ctx, service } = this;
const result = await service.article.lists();
if (result) { ctx.body = { status: 200, data: result }; } else { ctx.body = { status: 500, msg: "查询文章列表失败" }; } }
async detail() { const { ctx, service } = this;
const result = await service.article.detail(ctx.params.id);
if (result) { ctx.body = { status: 200, data: result }; } else { ctx.body = { status: 500, msg: "查询文章详情失败" }; } }
|