egg 常用代码模板
npm i
=> 修改 database/migrations 数据库配置
npm run dev
- 统一的成功/失败响应 json 格式
- 前后端分离文档
- 集成 ORM 库(sequelize)
- 根据 ORM 库,实现通用 model 模板
- 根据 ORM 库,实现通用的模型 "增删改查" service 模板
- 根据 "增删改查" service 模板,实现模型对应的 "增删改查" 控制器
- 给 "增删改查" 控制器模板增加更复杂的查询功能(findAll、count)
- Number 类型字段大于小于等于查询
- String 类型字段关键词查询
- 实现用户基础模型、通用功能接口、鉴权中间件
- 注册
- 登录
- 获取个人信息
- 修改密码
- jwt 鉴权中间件
对应的 json schema:
apidoc/schema/success.json
- 复制核心代码到自己项目中相同位置
app/extend/helper.js
- 控制器返回数据时,使用 ctx.helper.success 方法
/***
* {
* status: 200,
* msg: '请求成功',
* data: '响应数据'
* }
***/
ctx.helper.success(data, msg)
对应的 json schema:
apidoc/schema/fail.json
- 复制核心代码到自己项目中相同位置
/app/middleware/error.js
- 加载全局中间件
// config/config.default.js
config.middleware = [
'error'
]
- 使用 ctx.throw 方法
/**
* {
* status: 400,
* msg: '出错了'
* }
**/
ctx.throw(400, '出错了')
- 安装依赖
npm install -save-dev apidoc apidoc-plugin-schema
- package.json scripts 中定义打包命令
{
"build:docs": "apidoc -i app/ -o app/public/docs"
}
-
项目根目录创建 apidoc/schema 目录,并自定义 json 模型
-
写控制器时书写文档
/**
* @api { post } /login 登录
* @apiGroup 用户
*
* @apiSchema (请求头) {jsonschema=../../apidoc/schema/jwt-auth.json} apiHeader
*
* @apiParam (请求体) { String } username 账号
* @apiParam (请求体) { String } password 密码
*
* @apiSchema (成功响应) {jsonschema=../../apidoc/schema/success.json} apiSuccess
*
* @apiSuccess (data) { String/Number } id id
* @apiSuccess (data) { String } name 用户名
*
* @apiSchema (失败响应) {jsonschema=../../apidoc/schema/fail.json} apiSuccess
*/
- 使用命令生成文档
npm run build:docs
- 启动项目,访问文档
http://localhost:7001/public/docs/index.html
- 安装依赖
npm install --save egg-sequelize mysql2
npm install --save-dev sequelize-cli
- 注册插件
config/plugin.js
exports.sequelize = {
enable: true,
package: 'egg-sequelize'
}
- 创建 Migrations 配置文件
app/.sequelizerc
'use strict';
const path = require('path');
module.exports = {
config: path.join(__dirname, 'database/config.json'),
'migrations-path': path.join(__dirname, 'database/migrations'),
'seeders-path': path.join(__dirname, 'database/seeders'),
'models-path': path.join(__dirname, 'app/model'),
};
- 初始化 Migrations 配置文件和目录
执行完会生成 database 目录
npx sequelize init:config
npx sequelize init:migrations
- 配置各个环境的数据库信息
database/config.json
注意:别忘了加上了时区 "timezone": "+08:00"
{
"development": {
"username": "root",
"password": null,
"database": "egg-sequelize-doc-default",
"host": "127.0.0.1",
"dialect": "mysql",
"timezone": "+08:00"
},
"test": {
"username": "root",
"password": null,
"database": "egg-sequelize-doc-unittest",
"host": "127.0.0.1",
"dialect": "mysql",
"timezone": "+08:00"
}
}
- 在 egg 配置中引入 database/config.json 配置
config/config.default.js
const dbConfig = require('../database/config')
module.exports = appInfo => {
const userConfig = {
/* ... */
sequelize: {
...dbConfig[ process.env.NODE_ENV ]
}
/* ... */
}
}
- 同步表模型
app.js
在开发环境中使用 sync({ alter: true }) 同步
在线上环境中每张表的首次使用 sync() 同步,修改字段时使用 migrations 同步
module.exports = class {
constructor (app) {
this.app = app
}
async willReady () {
/**
* 在开发环境中使用 sync({ alter: true }) 同步
* 在线上环境中每张表的首次使用 sync() 同步,修改字段时使用 migrations 同步
**/
await this.app.model.sync({
alter: process.env.NODE_ENV === 'development'
})
}
}
模板文件:
app/model/A.js
app/service/A.js
app/controller/A.js
app/extend/helper.js
- 想一个模型名字(比如 Product)
- 复制 helper.js 到自己项目中(主要用 queryToOpQuery 方法)
- 复制 model,service,controller 模板,在对应目录下创建 product.js
- 在文件中找 MODEL_NAME 常量填 Product
- 在 model/product.js 中还要填 TABLE_NAME = products(复数小写形式)
- 定义 restful 路由,如下:
router.get('/product', controller.product.findAll)
router.get('/product/count', controller.product.count)
router.get('/product/:id', controller.product.findOne)
router.post('/product', controller.product.create)
router.put('/product/:id', controller.product.update)
router.delete('/product/:id', controller.product.delete)
备注:
- 在 app/controller/A.js 中已有统一 apidoc 文档注释,需要自行完善后,删除每一块顶部的 @apiIgnore 后启用
- 安装依赖
npm i --save jsonwebtoken passport-jwt passport-local egg-passport
- 复制以下代码到自己项目中
app/module/user.js
app/service/user.js
app/controller/user.js
app/middleware/passport-local.js
app/middleware/passport-jwt.js
- 开启 egg-passport 插件
// config/plugin.js
exports.passport = {
enable: true,
package: 'egg-passport'
}
- 添加 jwt sercet 配置
// config/config.default.js
const userConfig = {
jwt: {
secret: '加密钥匙'
}
}
- 初始化中间件
// app.js
const passportLocal = require('./app/middleware/passport-local')
const passportJwt = require('./app/middleware/passport-jwt')
class AppBootHook {
async willReady () {
// 所有的插件都已启动完毕,但是应用整体还未 ready
// 可以做一些数据初始化等操作,这些操作成功才会启动应用
passportLocal.init(this.app)
passportJwt.init(this.app)
this.app.passport.verify(async (ctx, payload) => {
switch (payload.provider) {
case 'local': {
return passportLocal.verify(ctx, payload)
}
case 'jwt': {
return passportJwt.verify(ctx, payload)
}
}
})
}
}
- 定义路由
下面 jwtAuth 为 jwt 鉴权中间件,可以在其他自定义接口中使用
// app/router.js
module.exports = app => {
const { router, controller } = app
const localAuth = app.middleware.passportLocal(
app.config,
app
)
const jwtAuth = app.middleware.passportJwt(
app.config,
app
)
router.post('/login', localAuth, controller.user.login)
router.post('/register', controller.user.register)
router.get('/me', jwtAuth, controller.user.getInfo)
router.put('/password', jwtAuth, controller.user.changePassword)
}
备注:
- 用户相关的接口 apidoc 注释文档以写好