Koa scaffolding
I made a KOA scaffolding, koA and mongodb combination, has uploaded GitHub. 👏 👏 👏 👏
portal
(Where the code is written)
To write the code, just add the route fill controller, as shown
The following analysis of what constitutes 👇
koa
const Koa = require('koa');
const app = new Koa();
// response
app.use(ctx => {
ctx.body = 'Hello Koa';
});
app.listen(3000);
Copy the code
See nguyen Yifeng koA framework for more
router
The official example
var Koa = require('koa');
var Router = require('koa-router');
var app = new Koa();
var router = new Router();
router.get('/', (ctx, next) => {
// ctx.router available
});
app
.use(router.routes())
.use(router.allowedMethods());
Copy the code
Practical example
// routers/index.js
const Router = require('koa-router')
const Controllers = require('./controller')({})
const dateNumberController = Controllers('date_number')
const router = new Router({
prefix: '/api'
})
router
.post(dateNumberController.getPath('add'), dateNumberController.add)
.get(dateNumberController.getPath(`select`), dateNumberController.find)
.post(dateNumberController.getPath(`remove`), dateNumberController.delect)
.post(dateNumberController.getPath(`update`), dateNumberController.update)
module.exports = router
// routers/controller.js
const controllerFunction = ({basePath = '.. /controllers/', router_path_function}) => (controllerName) => {
const divController = require([basePath, controllerName].join(' '))
const prefix = controllerName
class Controller extends divController {
prefix = ' '
getPath(name){
return router_path_function ? router_path_function(this.prefix, name) : `/${this.prefix}/${name}`
}
}
const controller = new Controller()
controller.prefix = prefix
returnController} module. Exports = controllers/ / controllers/ controllerFunction // controllers/date_number.js const router = require('./routers')
app.use(router.routes());
Copy the code
See koA-Router Github for more details
bodyparser
We have the route, but we also need the parameters passed from the front end, so we need to get the parameters first
example
app.use(async ctx => {
ctx.body = ctx.request.body;
});
Copy the code
Post requests are then parsed, either application/ JSON or Application/X-www-form-urlencoded
The effect
Update details at BodyParser GitHub
koa-parameter
Once we get the parameters we need to verify them
// main.js
const parameter = require("koa-parameter")
const error = require("koa-json-error") app.use(parameter(app)); Use (error({postFormat: (e, {stack,... Rest}) => ({stack, rest})})) // in CTX, such as in route ctx.verifyParams({date: {type: "string", required: true },
list: { type: "array", required: true}})Copy the code
mongodb
With the parameters in hand, the next step is to manipulate the data
basis
Initialize the
Install mongodb, then NPM install Mongoose, and initialize as follows
const mongoose = require('mongoose'// DB_ADDRESS = const DB_ADDRESS ="mongodb://localhost:27017/db"
mongoose.connect(DB_ADDRESS, {useNewUrlParser: true, useUnifiedTopology: true}, err => {
if (err) {
log.fatal({msg: '[Mongoose] database connect failed! ', err})
} else {
console.log('[Mongoose] database connect success! ')
}
})
module.exports = mongoose
Copy the code
Build a model
To use it, we need to create a set first (called a table in mysql), but MD is more flexible and can operate directly in the code, we need to create the model first.
const mongoose = require('mongoose'); const { Schema, model } = mongoose; // Data modellet DateNumberSchema = new Schema({
date: { type: String, required: true, unique: true },
list: { type: Array, require: true}}); module.exports = model('DateNumber', DateNumberSchema);
Copy the code
Operating database
check
const data = await DateNumber.find()
Copy the code
new
Const data = await to(new DateNumber({date, list}).save()Copy the code
delete
const data = await DateNumber.deleteOne({date: date})
Copy the code
change
const data = await DateNumber.updateOne({date}, {$set: {list}})
Copy the code
example
const DateNumber = require('.. /models/dateNumber')
class DateNumberController {
prefix = ' '
getPath(name){
return` /${this.prefix}/${name}`
}
async add(ctx, next){
ctx.verifyParams({
date: { type: "string", required: true },
list: { type: "array", required: true },
})
const {date, list} = ctx.request.body
const [err, data] = await to( new DateNumber({date, list}).save() )
if(err) return ctx.throw(500, err)
ctx.response.body = data
}
async find(ctx, next){
const data = await DateNumber.find()
ctx.response.body = data.join('\n')
log.info('find')
}
async delect (ctx, next){
ctx.verifyParams({
date: { type: "string", required: true },
})
const {date} = ctx.request.body
const data = await DateNumber.deleteOne({date: date})
ctx.response.body = data
}
async update(ctx, next){
ctx.verifyParams({
date: { type: "string", required: true },
list: { type: "array", required: true },
})
const {date, list} = ctx.request.body
const [err, data] = await to( DateNumber.updateOne({date}, {$set: {list}}) )
if(err) return ctx.throw(500, err)
ctx.response.body = data
}
}
module.exports = new DateNumberController()
Copy the code
Correspondence (from rookie Tutorial)
SQL terms/concepts | MongoDB terminology/concepts | Explanation/explanation |
---|---|---|
database | database | The database |
table | collection | Database tables/collections |
row | document | Data record line/document |
column | field | Data fields/fields |
index | index | The index |
table | joins | Table joins,MongoDB does not support |
primary | key | Primary key Specifies the primary key. MongoDB automatically sets the _ID field to the primary key |
MAC needs to run Mongod first, and then open a window, otherwise it will remind you that the service can’t be found; Windows has built-in visualization software. Install mongoDB Compass
to function
The code above uses to
To is a wrapper around a promise, in the form of [err, data], which has the advantage of not having to write a try catch and handling errors horizontally.
To is global and is introduced in main.js
The advanced
Paging query
New datenumber.find ().skip(count *(page -1)).limit(count)Copy the code
It would be slow without an index
Join the left collection query
db.orders.aggregate([
{
$lookup:
{
from: "inventory".localField: "item",
foreignField: "sku",
as: "inventory_docs"}}])Copy the code
Join tables for more queries
The log
Use log4JS to implement logging
use
var log4js = require('log4js');
var logger = log4js.getLogger();
logger.level = 'debug';
logger.debug("Some debug messages");
Copy the code
Level
Logs of the current level are generated
Output Settings
I set that the info output is normal, and the output is divided by date (so that the file is not too big). If there is a big problem like error, the email will be sent. Example is as follows, including the test code, you can configure the account password in the email to run
// example email: {host:'smtp.qq.com',
auth: {
user: 'Your QQ id @qq.com',
pass: 'Your password,',
},
recipients: 'Sender @126.com'
}
}
const LOGINFO = {
appenders: {
info: {
type: "DateFile",
category: 'dateFileLog',
filename: path.join(__dirname, './log/info/'),
pattern: "yyyy-MM-dd.log",
alwaysIncludePattern: true
},
email: {
type: '@log4js-node/smtp', // Sender: config.email.auth.user, // subject:'Latest error report',
SMTP: {
host: config.email.host,
auth: config.email.auth,
},
recipients: config.email.recipients
}
},
}
const log4js = require('log4js')
log4js.configure(LOGINFO)
const log_info = log4js.getLogger()
const log_error = log4js.getLogger('error') global.log = { debug: log_info.debug.bind(log_info), info: log_info.info.bind(log_info), warn: log_info.warn.bind(log_info), error: log_error.error.bind(log_error), fatal: Log_error.fatal. Bind (log_error),setTimeout(() => {
log.fatal({
msg: 'test',
err: 'fatal'})}, 400).Copy the code
Mailbox key access: enter qq mailbox, set up — — — — — — — — — — — > > account opening service: POP3 / SMTP service — — — — – > generate the authorization code
log.fatal({
msg: 'test',
err: 'fatal'
})
Copy the code
The effect
For details about log4js, see log4js github. For details about log4js email, see log4js-node/ SMTP github
other
Please give me a thumbs up. I’m going to level 3. Thank you
— 完 —