• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

Koa+mongodb实战

开发技术 开发技术 2周前 (05-12) 21次浏览

本人弄了一个koa脚手架,koa和mongodb组合而成, 已上传GitHub. :clap: :clap: :clap: :clap:

传送门

目录结构如上,一个控制器

(也就是写代码的地方)

,一个日志,一个数据库模型,一个路由,一个工具,和入口文件。

写代码只要添加路由 填充控制器就好了,如图所示

下面解析下有哪些构成的:point_down:

koa

const Koa = require('koa'); const app = new Koa(); // response app.use(ctx => { ctx.body = 'Hello Koa'; }); app.listen(3000); 复制代码

更多见 阮一峰koa框架

router

官方例子

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()); 复制代码

实战例子

// routers/index.js const Router = require('koa-router') const dateNumberController = require('../controllers/date_number') const router = new Router({ prefix: '/api' }) dateNumberController.prefix ='date_number' 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 // main.js const router = require('./routers') app.use(router.routes()); 复制代码

更多详情见 koa-router github

bodyparser

有了路由,但是我们还需要前端传递过来的参数,所以需要先获取参数

例子

app.use(async ctx => { ctx.body = ctx.request.body; }); 复制代码

这时候post请求就可以解析了,不管是 application/json 还是 application/x-www-form-urlencoded

效果

更新详情见 bodyparser GitHub

koa-parameter

拿到参数后我们需要校验它

// main.js const parameter = require("koa-parameter") const error = require("koa-json-error") app.use(parameter(app)); // 这个是json错误处理,可以自动抛出http status 422 app.use( error({ postFormat: (e, { stack, ...rest }) => ({ stack, rest }) }) ) // ctx里面,比如路由里面 ctx.verifyParams({ date: { type: "string", required: true }, list: { type: "array", required: true }, }) 复制代码

mongodb

拿到参数,我们下一步就是需要操作数据了

初始化

安装mongodb,然后npm安装 mongoose , 如下初始化即可

const mongoose = require('mongoose') // db是数据库名称哦,没有的话会自动创建 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 复制代码

建立模型

使用的时候,我们需要先建立集合(在mysql里面叫表),但是MD更灵活,可以直接在代码里面操作,我们先建立模型。

const mongoose = require('mongoose'); const { Schema, model } = mongoose; // 数据模型 let DateNumberSchema = new Schema({ date: { type: String, required: true, unique: true }, list: { type: Array, require: true }, }); module.exports = model('DateNumber', DateNumberSchema); 复制代码

操作数据库

const data = await DateNumber.find() 复制代码

新增

// 要和模型对应 const data = await to( new DateNumber({date, list}).save() 复制代码

const data = await DateNumber.deleteOne({date: date}) 复制代码

const data = await DateNumber.updateOne({date}, {$set: {list}}) 复制代码

例子

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() 复制代码

对应关系(来自菜鸟教程)

SQL术语/概念 MongoDB术语/概念 解释/说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins 表连接,MongoDB不支持
primary key primary key 主键,MongoDB自动将_id字段设置为主键

MAC的需要先运行mongod,然后再开一个窗口,不然会提醒找不到服务; Windows有自带的可视化软件,安装的时候install mongoDB compass勾上即可

to function

上面有一个代码用到了to

to是对promise的一个封装,变成[err, data] 这种形式,这样有一个好处是不需要写try catch,又可以平级处理错误。

to是全局的,在main.js引入

mongodb更多见 菜鸟教程

日志

使用 log4js 实现日志

使用方式

var log4js = require('log4js'); var logger = log4js.getLogger(); logger.level = 'debug'; logger.debug("Some debug messages"); 复制代码

Level

等级作用是,输出>=当前级别的日志

输出设置

我设置的是,info正常输出,输出的时候按日期分(这样文件不会太大),如果遇到error这种大问题就发邮件,例子如下,包含测试代码,你配置下email里面的账号密码就可以运行了

const config = { // 例子 email: { host: 'smtp.qq.com', auth: { user: '你的qq号@qq.com', pass: '你的密码,', }, recipients: '发送方@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: '测试', err: 'fatal' }) }, 400) 复制代码

邮箱密钥获取方式: 进入qq邮箱,设置—-> 账户 ——->开启服务:POP3/SMTP服务 —–>生成授权码

log.fatal({ msg: '测试', err: 'fatal' }) 复制代码

效果

log4js更多详情见 log4js github

log4js邮箱更多详情见 log4js-node/smtp github


程序员灯塔 , 版权所有
转载请注明原文链接:https://www.wangt.cc/2020/05/koamongodb%e5%ae%9e%e6%88%98/
喜欢 (0)