Koa2+mongoose

Why Koa
KOA Express is a framework with a company's products, is using the promise of a developer after node7.0 version api to express once again the package, named Koa, == Koa = Express + Promise == , and the use of middleware by the chain into a ring [onion]

Official website
User Notes

installation

cnpm i koa --save

The most basic use

const Koa = require('koa');
const app = new Koa();
app.listen(3000);

Middleware middleware
in the middle HTTP Request and HTTP Response, some intermediate function used to implement functions, called "middleware", each of intermediate default accepts two parameters, the first parameter is the Context object, the second It is the next function parameter. As long as the call to the next function, you can transfer execution to the next middleware
middleware we need to have

  • koa-body post processing request
  • koa-router handles the routing intelligence
  • koa2-cors cross-domain
  • mongoose database connection
  • log4js Journaling plug
  • module-alias reference path, the relative path to avoid very long

There are other middleware, because before and after use so the end of the separator less than

  • koa-staic, static file access
  • koa-view, rendering plug-in server
  • koa-session, koa built-cookie methods, only need to download session

My suggestion directory

  • An entry file called app.js or call server.js
  • A place some global configuration config.js
  • Api a folder to put my route
  • A request folder to put my request
  • Folder put a router routing configuration entry
  • Utils a folder to put some time to process, uuid plug-js
  • Folder put a mongoose connecting the inlet of the database, which then build a model folder
  • A middleware folder to put your own middleware

The codes
need to first install the top middleware

// app.js 入口文件

const Koa = require('koa')
const koaBody = require('koa-body');
const cors = require('koa2-cors')
const config = require('./src/config')
const router = require('./src/router')
//启动的时候连接一下mongodb,不需要use
const mongoose = require('./src/mongoose')  
// 自定义中间件
const whiteList = require('./src/middleware/whiteList')

const app = new Koa()
app.use(whiteList());  //白名单放第一位
app.use(koaBody({
    formLimit:10000 * 1024 * 1024,   //JSON 数据体的大小限制,默认56k
    textLimit:10000 * 1024 * 1024,   //限制表单请求体的大小,默认56k
    jsonLimit:10000 * 1024 * 1024,   //限制 text body 的大小,默认56k
    multipart: true,
        formidable: {
            maxFileSize: 2000 * 1024 * 1024    // 设置上传文件大小最大限制,默认2M
        }
}));
app.use(xmlParse());
app.use(cors());  //放到route前面,跨域
app.use(router.routes());
app.use(router.allowedMethods());

app.listen(config.port)
console.log('server start at port:', config.port)
// config.js

module.exports = {
    port: 3000,
    filePath:'E:\\nginx-1.16.1\\html\\uploadFile\\',   //开发环境
    // filePath:'/usr/local/nginx/html/uploadFile/',   //正式环境
    fileUrl : "http://localhost/uploadFile/",          //开发环境
    // fileUrl : "http://47.97.201.201/uploadFile/",   //正式环境
    // 白名单
    whiteList:[
        "127.0.0.1:8848",
        "127.0.0.1:8080"
    ]
}
// router/index.js

const Router = require('koa-router')
const router = new Router()

router.get('/get', api.get)
router.post('/post', api.post)
router.post('/uploadFile', api.uploadFile)
router.post('/uploadFiles', api.uploadFiles)
router.post('/uploadBase64', api.uploadBase64)

module.exports = router
// api/index.js

const upload = require('../util/upload')

exports.get  = async (ctx, next) => {
    get方式的取query的值
    let query = ctx.request.query;
    await next();
    ctx.body = query;  //返回值
}
exports.post  = async (ctx, next) => {
    //post取body的值
    let body = ctx.request.body;  
    await next();
    ctx.body = body;  //返回值
}
exports.uploadFile  = async (ctx, next) => {
    let body = ctx.request.body;
    var res = await upload.uploadFile(ctx)
    await next();
    ctx.body = {file:res};  //返回值
}
exports.uploadBase64  = async (ctx, next) => {
    let body = ctx.request.body;
    var res = await upload.uploadBase64(body.file,body.fileName)
    await next();
    ctx.body = {file:res};  //返回值
}
// util/upload.js

const path = require("path");
const fs = require("fs");
const uuid = require('./uuid');  // 自己写一个
const config = require('../config');
let Duplex = require('stream').Duplex;

exports.uploadFile = async function(ctx) {
    // 上传单个文件
    const file = ctx.request.files.file; // 获取上传文件
    // 创建可读流
    const reader = fs.createReadStream(file.path);
    let fileId = uuid()
    let fileName = file.name;
    let newName = fileId + "_" + fileName;
    let filePath = config.filePath + `${newName}`;
    // 创建可写流
    const stream = fs.createWriteStream(filePath);
    // 可读流通过管道写入可写流
    reader.pipe(stream);
    return {fileId,fileName,newName,fileUrl:config.fileUrl,url:filePath};
}

exports.uploadBase64 = async function(file,fileName) {
    // 上传单个base64
    // 创建可读流
    var base64 = file.replace(/^data:.+;base64,/,"");
    var buffer = Buffer.from(base64, 'base64');
    let fileId = uuid()
    let newName = fileId + "_" + fileName;
    let filePath = config.filePath + `${newName}`;
    let reader = new Duplex();
    reader.push(buffer);
    reader.push(null);
    const stream = fs.createWriteStream(filePath);
    // 可读流通过管道写入可写流
    reader.pipe(stream);
    return {fileId,fileName,newName,fileUrl:config.fileUrl,url:filePath};
}
// mongoose/index.js

var mongoose = require('mongoose');
mongoose.set('useFindAndModify', false)
mongoose.connect('mongodb://localhost/mydb',{useNewUrlParser:true,useUnifiedTopology: true},function(err){
    if(err){
        console.log('Connection Error:' + err)
    }else{
        console.log('mongoose Connection success!')
    }
});

module.exports = mongoose;
// 自定义白名单中间件
// middleware/whiteList.js

const config = require('../config')

module.exports = () => {
    return async (ctx, next) => {
        var referer = ctx.request.header.referer;
        var origin = ctx.request.header.origin;
        if(referer==undefined||origin==undefined){
            await next()  //可以再网页之外访问
        }else{
            let whiteList = config.whiteList;
            if(whiteList.includes(origin.split("//")[1])){
                await next()
            }else{
                ctx.body = "访问地址不在白名单内";
            }
        }
    }
}
// utils/logger.js 

const log4js = require('log4js'); 
const path = require('path') 
// 定义log config 
log4js.configure({ 
  appenders: { 
     // 定义两个输出源 
     info: { type: 'file', filename: path.resolve('log/info.log') }, 
     error: { type: 'file', filename: path.resolve('log/error.log') } 
  }, 
  categories: { 
     // 为info/warn/debug 类型log调用info输出源 error/fatal 调用error输出源 
     default: { appenders: ['info'], level: 'info' }, 
     info: { appenders: ['info'], level: 'info' }, 
     warn: { appenders: ['info'], level: 'warn' }, 
     debug: { appenders: ['info'], level: 'debug' }, 
     error: { appenders: ['error'], level: 'error' }, 
     fatal: { appenders: ['error'], level: 'fatal' }, 
  } 
}); 
// 导出5种类型的 logger 
module.exports = { 
   debug: (...params) => log4js.getLogger('debug').debug(...params), 
   info: (...params) => log4js.getLogger('info').info(...params), 
   warn: (...params) => log4js.getLogger('warn').warn(...params), 
   error: (...params) => log4js.getLogger('error').error(...params), 
   fatal: (...params) => log4js.getLogger('fatal').fatal(...params), 
} 

//  使用
const logger = require('./utils/logger.js')
//  记录访问,可以自己写一个中间件
logger.info('请求url:', url , method||'get', JSON.stringify(data))

The above code, equipped with a direct Koa projects, including the code files to upload, mongodb database connections, routing how to write, as well as the white list filter that uses mongoose mongoose notes of view, the next micro-channel server connected with Koa

Egg
addition to these two frameworks, and one Eggis Ali package, Egg document says so, == Egg inherited from Koa, as described above, Koa is a very good framework, but for enterprise-class applications, it is also a basis for comparison, and Koa Egg chose as its basic framework, based on its model, it made some further enhancements ==, I read his document uses, it should be to add Koa Java MVC pattern integration and then together, == Egg = Koa + MVC == , this framework more strictly regulate the enterprise, so that each route inside the frame inherits Controllerclasses and Serviceclasses, and query the database to keep this in, you can call at any time, == he is the best method is to use a file path to the execution of ==, very much like Java framework annotations scanned, the code below

// app/router.js
module.exports = app => {
  app.router.get('/user/:id', app.controller.user.info);
};

// app/controller/user.js
const Controller = require('egg').Controller;
class UserController extends Controller {
  async info() {
    const { ctx } = this;
    const userId = ctx.params.id;
    const userInfo = await ctx.service.user.find(userId);
    ctx.body = userInfo;
  }
}
module.exports = UserController;

// app/service/user.js
const Service = require('egg').Service;
class UserService extends Service {
  // 默认不需要提供构造函数。
  // constructor(ctx) {
  //   super(ctx); 如果需要在构造函数做一些处理,一定要有这句话,才能保证后面 `this.ctx`的使用。
  //   // 就可以直接通过 this.ctx 获取 ctx 了
  //   // 还可以直接通过 this.app 获取 app 了
  // }
  async find(uid) {
    // 假如 我们拿到用户 id 从数据库获取用户详细信息
    const user = await this.ctx.db.query('select * from user where uid = ?', uid);

    // 假定这里还有一些复杂的计算,然后返回需要的信息。
    const picture = await this.getPicture(uid);

    return {
      name: user.user_name,
      age: user.age,
      picture,
    };
  }

  async getPicture(uid) {
    const result = await this.ctx.curl(`http://photoserver/uid=${uid}`, { dataType: 'json' });
    return result.data;
  }
}
module.exports = UserService;

// curl http://127.0.0.1:7001/user/1234

Guess you like

Origin www.cnblogs.com/pengdt/p/12072508.html