Koa+Mongoose实现增删改查功能

背景

最近在学习node相关的知识,说到后台就少不了数据库等知识,综合查阅的资料,我使用的是koa+mongodb+mongoose.在这篇文章中我会详细介绍这个项目的搭建过程,以及开发过程中遇到的坑点以及需要注意的点,适合初学者快速入门。

资源准备

本文后mvc台架构参考的是廖雪峰的koa mvc架构

后台搭建项目地址 koa-learn 代码才是硬道理。

对应的前端代码搭建过程,内含代码地址。 mixsys

mongoose连接mongoldb 这个最好看一下,涉及到一些项目介绍。

前端代码就是简单的react+redux的知识,框架搭建上面文章介绍的很详细,后期我加了一些增删改查的逻辑以及升级了网络访问的工具方法。

正文

说到项目就要从入口开始说起,app.js,一些基础的建表功能,上述mongoose连接mongodb中已有介绍,这里不多说。剩下的中间件我用的不多,但是node本身社区提供了大量优秀的中间件,你也可以自己编写中间件(下面的handler其实就是一个中间件),我就简单说说项目中用到的几个。

bodyParser()是解析网络访问发送的body数据的,比如Post请求发送用户名密码。

cors()是用于处理跨域问题的,跨域问题后端要允许跨域,前端也要支持跨域,两者缺一不可。

templateing是模板,通过后台访问,可以返回给浏览器一个web页面,参见浏览器中输入http://localhost:8080/返回的页面,这就是自己定义的。

最重要的是controller(),这个是引入了你定义的所有一系列操作,在服务器启动的时候把你所有生命的处理函数都注册进来,是后台访问的初始化操作。

最后说一句,由于node洋葱模型,app.use()使用的数据是有先后分别的,要注意一下(参见下方错误处理,就要放在第一个来use())。

错误处理

首先可以看到的就是我声明了一个handler变量,如下

const handler = async (ctx, next) => {
try {
	await next()
} catch (error) {
    ctx.response.body = {
        error: true,
        code: '00000',
        message: '服务器异常',
        desc: error.message
        }
    }
}

然后,在数据库连接成功之后,第一个就使用了app.use(handler)这个语句,这里我着重介绍一下这样写的原因。

在我们进行网络访问的时候,肯定不会所有的请求都不报错,那如果遇到报错就需要一个错误处理机制来处理错误,要保证前端调用人员知道错误的原因,而不是什么都不返回,任其抛出错误。

node的***洋葱模型***如果大家可以理解的话,看到这个语句,就知道这个catch语句时最后执行的,也就是说,在接下来的任何过程中执行出错了,都可以通过这句话将错误信息返回到前端,而不是直接抛出一个500服务器错误。

打个比方,下面的例子,name是要求unique的,也就是不能重复,假设我添加一个与之前名字相同的用户,那数据库肯定会报错,从而不会执行ctx.body这句话,直接服务器异常了。

var employee = new ctx.models.Employee({
	name:name,
	age:age,
	salary:salary,
	phone:phone,
})
let a = await employee.save();
ctx.body = a;

增删改查

先说增加,增加在mongoose中有个save()方法,可以参照controllers/data.js文件中 POST /createEmployee创建员工的方式。这里说一下增加,其他的异曲同工。使用await等待save()执行完成,避免完成前默认返回Not Found.然后执行完成之后返回执行结果,前端根据结果判断执行结果。如果执行过程中发生异常,那么就会被一开始设置的handler捕获到,从而返回错误信息,保证都是可以返回结果的,而不是500错误。

'POST /createEmployee': async (ctx, next) => {
   var name = ctx.request.body.name || '';
   var age = ctx.request.body.age || '';
   var salary = ctx.request.body.salary || '';
   var phone = ctx.request.body.phone || '';
   var employee = new ctx.models.Employee({
       name:name,
       age:age,
       salary:salary,
       phone:phone,
  })
  let a = await employee.save();
  ctx.body = a;
},

再说删除,参照controllers/data.js文件中DELETE /deleteEmployee方法。

'DELETE /deleteEmployee': async (ctx, next) => {
    let rst = await ctx.models.Employee.deleteOne({'name': ctx.request.query.name});
    ctx.response.body = rst;
},

修改,参照同文件中PUT /updateEmployee方法。

'PUT /updateEmployee': async (ctx, next) => {
    var name = ctx.request.body.name || '';
    var age = ctx.request.body.age || '';
    var salary = ctx.request.body.salary || '';
    var phone = ctx.request.body.phone || '';
    let obj = {
      name,
      age,
      salary,
      phone
    }
    let rst = await ctx.models.Employee.updateOne({'name':ctx.request.query.name}, obj);
    ctx.response.body = rst;
},

查询,参照同文件中GET /tabledata方法,以及GET /users方法,其中users提供了根据参数来查询的方式。可以通过url?name=xiaogang的方式来查询。

'GET /users': async (ctx, next) => {
    var query = ctx.request.query; // if nothing to pass just return a {}
    var rst = [];
    if (query.name) {
      rst = await ctx.models.User.find({userName: query.name});
    }else {
      rst = await ctx.models.User.find(); // if no name params,just query all users
    }
    ctx.response.body = {users: rst};
 },

多说一句

这里在data.js文件中,还有个GET /wormpic,这个方法实现了通过node从网络抓取数据。

还有controllers/signin.js文件中,POST /zhece方法的注释部分,他实现了Node发送邮件的功能。

有兴趣的可以了解一下。

结束

文章写到这里就差不多了,如果大家有什么指导意见,欢迎留言,相互进步。

你可能感兴趣的:(Some,meaningful)