1. Convention over Configuration
- Preset the default configuration
- Generate configurations based on custom conventions
- Only special configurations are required
- The goal is to simplify the configuration by doing little convention generation code logic
2. MVC architecture of Egg
- Controller: The control layer that interacts with view, model, and serive to perform database operations
- Service: General business logic layer, SMS/email, image upload encapsulation, or access to the database
- Model: Database persistence operation
- View: The view layer, generally egg only provides services, does not do HTML output
- Router: Distributes different controller control layers uniformly through routes.
3. Structure directory
3. Implement the architecture diagram yourself
- JGG unified hypervisor entry bus, including KOA instantiation and startup, jGG-Loader loaded out of all module functions
- Jgg-loader implements folder traversal, loading all classes under the folder, key value and method mapping
- All modules are passed in via JGG instance $app for data sharing
4. Specific code implementation
// KoA koa- Router node-schedule sequelize
//index.js
const jgg = require("./jgg")
const app = new jgg()
app.start(3000)
//jgg.js
const koa = require('koa')
const {initRoute,initController,initService,initConfig,initSchedule} = require('./jgg-loader')
class jgg {
constructor(conf){
this.$app = new koa(conf)
initConfig(this)
initSchedule(this)
this.$service = initService(this)
this.$ctrl = initController(this)
this.$app.use(initRoute(this).routes())
}
start(port){
this.$app.listen(port, () = > {
console.log("Server is up, port.",port)
})
}
}
module.exports = jgg
//jgg-loader.js
const fs = require('fs')
const path = require('path')
const Router = require('koa-router')
function load(dir,cb) {
console.log("dir",dir)
const url = path.resolve(__dirname,dir)
const files = fs.readdirSync(url)
files.forEach( filename= > {
// remove the suffix
filename = filename.replace('.js'.' ')
// Import the file
const file = require(url + '/' + filename)
cb(filename, file)
})
}
function initRoute(app) {
const router = new Router()
load("routes".(filename,fileObj) = > {
console.log(filename,fileObj)
if(typeof fileObj === 'function') {
fileObj = fileObj(app)
}
let prefix = filename === 'index' ? ' ': "/" + filename
Object.keys(fileObj).forEach( key= > {
let [method,path] = key.split("")
console.log('Mapping address${method.toLocaleUpperCase()} ${prefix}${path}`)
console.log("fileObj ",fileObj)
let func = fileObj[key]
router[method](prefix + path,async ctx => {
app.ctx = ctx
await func(app)
})
})
})
return router;
}
function initController(app) {
let controllers = []
load("controllers".(filename,fileObj) = > {
controllers[filename] = fileObj(app)
})
return controllers;
}
function initService(app) {
let services = []
load("service".(filename,fileObj) = > {
services[filename] = fileObj(app)
})
return services;
}
/ / timer
const schedule = require("node-schedule")
function initSchedule(app) {
load("schedule".(filename,fileObj) = >{ schedule.scheduleJob(fileObj.interval, fileObj.handler); })}const Sequelize = require('sequelize')
function initConfig(app) {
load('conf'.(filename, conf) = > {
if (conf.db) {
app.$db = new Sequelize(conf.db)
// Load the model
app.$model = {}
load('model'.(filename, { schema, options }) = > {
app.$model[filename] = app.$db.define(filename, schema, options)
})
app.$db.sync()
}
if (conf.middleware) {
conf.middleware.forEach(mid= > {
const midPath = path.resolve(__dirname, 'middleware', mid)
app.$app.use(require(midPath))
})
}
})
}
module.exports = {
initRoute,initController,initService,initConfig,initSchedule
}
//routes/index.js
module.exports = (app) = > ({
"get /" : app.$ctrl.home.index,
"get /detail" : app.$ctrl.home.detail,
})
//routes/user.js
module.exports = (app) = > ({
"get /aaa": async app => {
const name = await app.$service.user.getName()
app.ctx.body = "Xxx111 users" + name;
},
// /user/info
"get /info": app= > {
app.ctx.body = "XXX user age"+ app.$service.user.getAge(); }})//controller/home.js
module.exports = (app) = > ({
index : async app => {
// const name = await app.$service.user.getName()
// app.ctx.body = "con" + name;
app.ctx.body = await app.$model.user.findAll()
},
detail : async app => {
const name = await app.$service.user.getAge()
app.ctx.body = "con"+ name; }})//service/user.js
const delay = (data, tick) = > new Promise(resolve= > {
setTimeout(() = > {
resolve(data)
}, tick)
})
module.exports = (app) = > ({
getName() {
return app.$model.user.findAll()
},
getAge() {
return 20}})//model/user.js
const { STRING } = require("sequelize");
module.exports = {
schema: {
name: STRING(30)},options: {
timestamps: false}};//conf/index.js Configuration information
module.exports = {
db: {
dialect: 'mysql'.host: '81.71. XXX. XXX'.database: 'xxxx'.username: 'root'.password: 'xxxx'
},
middleware: ['logger']}//middleware/logger.js
module.exports = async (ctx, next) => {
console.log(ctx.method + "" + ctx.path);
const start = new Date(a);await next();
const duration = new Date() - start;
console.log(
ctx.method + "" + ctx.path + "" + ctx.status + "" + duration + "ms"
);
};
//schedule/log.js
module.exports = {
interval:'*/3 * * * * *'.handler(){
console.log('Timed task heh heh every three seconds'+ new Date()}}Copy the code