1.集成swagger
npm install egg-swagger-doc-feat -s
//注意需要在app/contract 才会自动解析
//定义文件夹app/contract/index.js 对象格式
module.exports = {
baseRequest: {
id: {
type: 'string',
description: 'id 唯一键',
required: true,
example: '1'
},
},
baseResponse: {
code: {
type: 'integer',
required: true,
example: 0
},
data: {
type: 'string',
example: '请求成功'
},
errorMessage: {
type: 'string',
example: '请求成功'
},
},
};
//定义app/contract/user.js对象格式
module.exports = {
createUserRequest: {
mobile: {
type: 'string',
required: true,
description: '手机号',
example: '18801731528',
format: /^1[34578]\d{9}$/,
},
password: {
type: 'string',
required: true,
description: '密码',
example: '111111',
},
realName: {
type: 'string',
required: true,
description: '姓名',
example: 'Tom'
},
},
}
//config/plugin.js
//添加插件
module.exports = {
swaggerdoc: {
enable: true,
package: 'egg-swagger-doc-feat',
}
};
// config.default.js
//定义接口格式
config.swaggerdoc = {
dirScanner: './app/controller',
apiInfo: {
title: '接口',
description: '接口 swagger-ui for egg',
version: '1.0.0',
},
schemes: ['http', 'https'],
consumes: ['application/json'],
produces: ['application/json'],
enableSecurity: false,
routerMap: true,
enable: true,
}
//定义文档类
//app/controller/user.js
const Controller = require('egg').Controller
/**
* @Controller 用户管理
*/
class UserController extends Controller {
constructor(ctx) {
super(ctx)
}
/**
* @summary 创建用户
* @description: 创建用户,记录用户信息
* @router post /api/user
* @request body createUserRequest *body
* @reponse 200 baseResponse 创建成功
*/
async create() {
const {ctx} = this
// ap11p()
// ctx.body = 'user ctrl'
// ctx.body = this.success()
const res = {aa:'ddd'}
ctx.helper.success({ctx, res})
}
}
module.exports = UserController
//测试地址:http://localhost:7001/swagger-ui.html
2.统一异常处理
//注意需要在app/middleware文件夹下 才会自动解析
// /middleware/error_handler.js
'use strict'
module.exports = (option, app) => {
return async function (ctx, next) {
try {
await next()
} catch (err) {
// 所有的异常都在 app 上触发一个 error 事件,框架会记录一条错误日志
app.emit('error', err, this)
const status = err.status || 500
// 生产环境时 500 错误的详细错误内容不返回给客户端,因为可能包含敏感信息
const error = status === 500 && app.config.env === 'prod' ?
'Internal Server Error' :
err.message
// 从 error 对象上读出各个属性,设置到响应中
ctx.body = {
code: status, // 服务端自身的处理逻辑错误(包含框架错误500 及 自定义业务逻辑错误533开始 ) 客户端请求参数导致的错误(4xx开始),设置不同的状态码
error: error
}
if (status === 422) {
// ctx.body.detail = err.errors
}
ctx.status = 200
}
}
}
//注册中间件
//config/config.default.js
config.middleware = ['errorHandle']; //注意这里需要把error_handler.js 调整成驼峰命名
//在对应的Controller 故意报错
const Controller = require('egg').Controller;
class HomeController extends Controller {
async index() {
const { ctx } = this;
aa() //调用没用定义的方法测试
ctx.body = 'hi, egg';
}
}
module.exports = HomeController;
3.通用工具类
//注意需要在app/extend文件夹下 才会自动解析
//app/extend/helper.js
const moment = require('moment')//使用日期工具
// 处理成功响应
exports.success = ({ ctx, res = null, msg = '处理成功' }) => {
ctx.body = {
code: 0,
data: res,
msg
}
ctx.status = 200
}
// 格式化时间
exports.formatTime = time => moment(time).format('YYYY-MM-DD HH:mm:ss')
//测试
const Controller = require('egg').Controller
class UserController extends Controller {
constructor(ctx) {
super(ctx)
}
async create() {
const {ctx} = this
// ap11p()
const res = {aa:'ddd'}
ctx.helper.success({ctx, res})//调用继承的工具类
}
}
module.exports = UserController
4.添加校验
//安装库
npm i egg-validate -s
//config/plugin.js
validate: {
enable: true,
package: 'egg-validate'
},
//controller/user.js
async create() {
const { ctx, service } = this // 校验参数
ctx.validate(ctx.rule.createUserRequest)
}
5.添加model层
//安装库
npm install egg-mongoose -s
//config/plugin.js
mongoose : {
enable: true,
package: 'egg-mongoose',
}
// config.default.js
config.mongoose = { url: 'mongodb://127.0.0.1:27017/xxx',
options: { // useMongoClient: true,
autoReconnect: true,
reconnectTries: Number.MAX_VALUE,
bufferMaxEntries: 0,
},
}
//app/model/user.js
module.exports = app => {
const mongoose = app.mongoose
const UserSchema = new mongoose.Schema({
mobile: { type: String, unique: true, required: true },
password: { type: String, required: true },
realName: { type: String, required: true },
avatar: { type: String, default: 'https://1.gravatar.com/avatar/a3e54af3cb6e157e496ae430aed4f4a3?s=96&d=mm' },
extra: { type: mongoose.Schema.Types.Mixed },
createdAt: { type: Date, default: Date.now }
})
return mongoose.model('User', UserSchema)
}
6.添加service
npm install egg-bcrypt -s
//app/service/user.js
const Service = require('egg').Service
class UserService extends Service {
/**
* 创建用户
* @param {*} payload
*/
async create(payload) {
const { ctx, service } = this
payload.password = await this.ctx.genHash(payload.password)
return ctx.model.User.create(payload)
}
}
module.exports = UserService
//app/controller/user.js
const Controller = require('egg').Controller
/**
* @Controller 用户管理
*/
class UserController extends Controller {
constructor(ctx) {
super(ctx)
}
/**
* @summary 创建用户
* @description: 创建用户,记录用户信息
* @router post /api/user
* @request body createUserRequest *body
* @reponse 200 baseResponse 创建成功
*/
async create() {
const {ctx} = this
// ap11p()
// ctx.body = 'user ctrl'
// ctx.body = this.success()
ctx.validate(ctx.rule.createUserRequest)
const palyload = ctx.request.body || {}
const res = await this.service.user.create(palyload)
// const res = {aa:'ddd'}
ctx.helper.success({ctx, res})
}
}
module.exports = UserController
5.基于领域模型自动初始化数据
//egg根目录新增/app.js文件
//添加钩子函数
//程序每次启动执行
async didReady() {
console.log('========Init Data=========')
const ctx = await this.app.createAnonymousContext();
await ctx.model.User.remove(); //每次都自动清空数据
await ctx.service.user.create({ mobile: '13611388415', password: '111111', realName: '老夏', }) }//自动插入用户信息
6.配置跨域
config\plugin.js
//打开跨域
exports.cors = {
enable: true,
package: "egg-cors",
};
config\config.default.js
module.exports = (appInfo) => {
const config = (exports = {});
config.security = {
csrf: {
enable: false,
ignoreJSON: true,
},
domainWhiteList: ["*"], // []中放放出的白名单,*代表所有
};
config.cors = {
origin: "*",
allowMethods: "GET,HEAD,PUT,POST,DELETE,PATCH",
credentials: true,
};
return {
...config,
...userConfig,
};
};