基于 Koa 的企业级 Node.js 框架(阿里开源)
约定优于配置(Convention over Configuration)
插件化架构,内置多进程管理、日志、安全等能力
适合中大型企业应用,提供完整 MVC 解决方案
egg-project
├── app
│ ├── controller # 控制器
│ ├── service # 业务逻辑
│ ├── model # 数据模型(可选)
│ ├── middleware # 中间件
│ ├── router.js # 路由配置
│ └── extend # 扩展(helper、filter等)
├── config
│ ├── config.default.js # 默认配置
│ ├── config.prod.js # 生产环境配置
│ └── plugin.js # 插件配置
└── test # 单元测试
对象 | 说明 |
---|---|
Application |
全局应用对象(单例) |
Context |
请求上下文(封装 request/response ) |
Controller |
处理用户输入,返回响应 |
Service |
业务逻辑封装 |
Helper |
工具函数 |
Logger |
日志对象 |
app/router.js
)module.exports = app => {
const { router, controller } = app;
router.get('/user/:id', controller.user.info); // RESTful 风格
router.post('/api/login', controller.auth.login);
};
router.resources('posts', '/api/posts', controller.posts); // 自动生成 CRUD 路由
router.get('/admin', app.middleware.auth(), controller.admin.index);
// app/controller/user.js
const Controller = require('egg').Controller;
class UserController extends Controller {
async info() {
const { ctx } = this;
const userId = ctx.params.id;
const user = await ctx.service.user.find(userId);
ctx.body = user;
}
}
ctx
方法方法 | 说明 |
---|---|
ctx.query |
获取查询参数 |
ctx.params |
获取路由参数 |
ctx.request.body |
获取请求体(需 bodyParser ) |
ctx.redirect(url) |
重定向 |
ctx.render(view, data) |
渲染模板 |
ctx.status = 200 |
设置状态码 |
业务逻辑封装(避免 Controller 臃肿)
可复用(多个 Controller 调用同一个 Service)
支持 async/await
// app/service/user.js
const Service = require('egg').Service;
class UserService extends Service {
async find(id) {
return await this.app.mysql.get('user', { id });
}
}
const user = await ctx.service.user.find(1);
// app/middleware/auth.js
module.exports = (options, app) => {
return async (ctx, next) => {
if (!ctx.session.user) {
ctx.throw(401, 'Unauthorized');
}
await next();
};
};
// config/config.default.js
exports.middleware = ['auth']; // 全局中间件
// 或局部使用
router.get('/admin', app.middleware.auth(), controller.admin.index);
插件 | 用途 |
---|---|
egg-mysql |
MySQL 数据库 |
egg-sequelize |
Sequelize ORM |
egg-redis |
Redis 客户端 |
egg-validate |
参数校验 |
egg-jwt |
JWT 认证 |
// config/plugin.js
exports.mysql = {
enable: true,
package: 'egg-mysql',
};
// config/config.default.js
exports.mysql = {
client: {
host: '127.0.0.1',
port: '3306',
user: 'root',
password: '123456',
database: 'test',
},
};
egg-mysql
// 查询
const user = await this.app.mysql.get('user', { id: 1 });
// 插入
await this.app.mysql.insert('user', { name: 'Tom' });
// 更新
await this.app.mysql.update('user', { name: 'Jerry' }, { where: { id: 1 } });
egg-sequelize
// app/model/user.js
module.exports = app => {
const { STRING, INTEGER } = app.Sequelize;
return app.model.define('user', {
name: STRING,
age: INTEGER,
});
};
// 查询
const user = await ctx.model.User.findOne({ where: { id: 1 } });
// 存储
await app.redis.set('key', 'value');
// 读取
const value = await app.redis.get('key');
功能 | 说明 |
---|---|
CSRF 防护 | 默认开启(需 ctx.csrf 获取 token) |
XSS 过滤 | 内置 egg-security 中间件 |
SQL 注入防护 | ORM 自动转义 |
HTTPS 支持 | 配置 config.prod.js |
优化点 | 方法 |
---|---|
多进程 | 基于 cluster 自动管理 |
缓存 | Redis + 内存缓存 |
日志切割 | egg-logrotator |
静态资源 CDN | 配置 config.static |
// test/controller/user.test.js
const { app, mock } = require('egg-mock');
describe('GET /user/:id', () => {
it('should return user info', () => {
return app.httpRequest()
.get('/user/1')
.expect(200);
});
});
方式 | 说明 |
---|---|
PM2 | pm2 start npm -- start |
Docker | 官方提供 egg-docker |
Serverless | 阿里云 FC / AWS Lambda |
特性 | Express | Koa | Egg | NestJS |
---|---|---|---|---|
定位 | 轻量级 | 更现代的 Koa | 企业级 | 全栈框架 |
中间件模型 | 线性 | 洋葱圈 | 增强版 Koa | 模块化 + DI |
适合场景 | 小型 API | 轻量级应用 | 中大型应用 | 复杂后端 |
Egg.js 官方文档
Egg.js 最佳实践
阿里云 Egg.js 教程
Egg.js 适合需要标准化、可维护的企业级 Node.js 开发,尤其适合团队协作项目。