koa、mongodb、mvc构建服务端

【这是我参与更文挑战的第14天,活动详情查看: 更文挑战

1、先初始化一个koa2的服务端项目,然后安装项目中所需要的依赖模块:image.png

2、分别创建controller、model、routes文件夹,分别对应的是业务逻辑、mongoose的model、路由接口

image.png

3、配置入口文件app.js,实例化koa和koa-router装载子路由、连接数据库及端口

const Koa = require('koa');
const Router = require('koa-router');
const mongoose = require('mongoose);
const api = require('./routes/api/user);

//配置跨域
app.use(async (ctx, next) => {
  //*表示任何域名都可以访问
  ctx.set('Access-Control-Allow-Origin', '*');
  ctx.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
  ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
  if (ctx.method == 'OPTIONS') {
    ctx.body = 200;
  } else {
    await next();
  }
});

//实例化
const app = new Koa();
const router = new Router();

//加载路由中间件
app.use(router.routes()).use(router.allowedMethods());

//子路由装载
router.use('/', api.routes())

//连接数据库
mongoose.connect('mongodb://localhost/student', { useNewUrlParser: true, useUnifiedTopology: true })
	.then(() => console.log('mongodb connected...'))
	.catch(err => console.log(err));

//判断是开发环境还是生产环境,若是生产环境就使用生产环境的默认端口
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`server starting on ${prot}`));
复制代码

注意:

  • 在启动前一定要先启动mongodb数据库的服务,命令:mongod –dbpath ‘文件路径’;一定要有一个文件,否则会mongodb的服务启动会失败
  • 若没有在package.json中配置启动的话,则要使用原生的node启动app.js,命令:node app.js
  • 配置package.json,因为我们时常要改动代码,所以我们用nodemon来帮我们时时监听启动
  • 安装nodemon,命令: image.png;-D是开发环境用的依赖、-S是生产环境用的依赖
  • 安装完成之后依赖可以package.json中查;-D对应的是devDependencies、-S对应的是dependencies;如:image.png
  • 在package.json中将原来的更改为nodemon启动:image.png
  • 现在就可以用命令:image.png启动了,如图就启动成功了:image.png

4、上面三步就已经成功的搭建了一个端口为5000的服务端了,并且还成功的连接了mongodb数据库
5、在model/user中定义mongoose的Schema

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

//创建表中的列名
const userSchema = new Schema({
    name: {
        type: String,
        required: true  //当required为true时必须传参,当不写required时,默认为false
    },
    tel: {
        type: String,
        required: true 
    }
});
//将创建的userSchema定义表名为user
const User = mongoose.model('user', userSchema);
module.exports = User;
复制代码

6、在controller/user中处理业务逻辑

const User = require('../models/user');
module.exports = {
    //获取所有数据
    list: async () => {
        try {
            // let data = [];
            let res = await User.find({}, (err, docs) => {
                if (!err) {
                    // data = docs;
                    return docs;
                }
                else {
                    console.log(err);
                };
                // console.log(data)
            }); 
            return res;
        } catch (err) {
            console.log(err)
        }
    },

    //根据tel获取单个信息
    show: async ctx => {
        const res = await User.find({ tel: ctx.params.tel }).countDocuments();
        if (res) {
            await User.findOne({ tel: ctx.params.tel }, (err, docs) => {
                if (!err) {
                    ctx.body = docs;
                }
                else {
                    console.log(err);
                };
            });
        }
        else {
            ctx.body = { status: 404, msg: '没有这个人的信息' }
        }

    },
  
		//添加信息
    create: async (user) => {
        const newUser = new User({ name: '', tel: '' });
        newUser.name = user.name;
        newUser.tel = user.tel;
        let save_user = {};
        try {
            save_user = await newUser.save();
            //console.log(save_user);
        } catch (err) {
            console.log(err);
        }
        return save_user;
    },
  
    //根据电话号码删除信息
    del: async (_id) => {
        const res = await User.findOne({ _id }).countDocuments();
        // console.log(tel);
        if (res > 0) {
            const res = await User.deleteOne({ _id });
            if (res.ok = 1) {
                return '删除成功';
            }
            else {
                return '删除失败';
            }
        } else {
           return { code: 404, msg: '没有这个人的信息' };
        }

    },

    //根据传入的tel更新数据
    update: async (_id, data) => {
        const res = await User.findOne({ _id }).countDocuments();
        if (res > 0) {
            const res = await User.updateOne({ _id }, data); //返回的res为   
            if (res.n === 1) {
                return '修改成功';
            }
            else {
                return '修改失败';
            }
        }
        else {
            return { status: 404, msg: '没有这个人的信息' }
        }

    }
};
复制代码

7、在routes/api/user.js中搭建restful风格的路由接口

const Router = require('koa-router');
let router = new Router();
const koaBody = require('koa-body')({ multipart: true });
const { create, list, update, del } = require('./controller/users');

//获取全部数据
router.get('/contactList', async ctx => {
	const res = await list();
	ctx.body = {status: 200, data: res}
});

//添加数据 以form-data格式提交数据
router.post('/contact/new/form', koaBody, async ctx => {
	let newData = ctx.request.body; //newData是个对象
  //引入controller中的users的create并传入一个对象
	let result = await create(newData);
  //返回给前端result和状态码
	ctx.body = {
		code: 200,
		data: result
	};
});

//添加数据 以json格式提交数据
router.post('/contact/new/json', async ctx => {
	let newData = ctx.request.body; //newData是个对象
	// 调用controller中的create接口将数据保存到数据库中
	let result = await create(newData)
	ctx.body = {
		code: 200,
		data: result
	}
});

//更新数据
router.put('/contact/edit', async ctx => {
	let newData = ctx.request.body;//这是一个对象
	const id = ctx.request.body._id;
  //将id传入调用的update中
	const res = await update(id, newData);
	ctx.body = { code: 200, data: res }
});
router.patch('/contact/edit', async ctx => {
	let newData = ctx.request.body
	// console.log(newData)
	const id = ctx.request.body._id;
	const res = await update(id, newData);
	ctx.body = { code: 200 }
	ctx.body = { data: res }
});

//删除数据,上传一个唯一标识判断是否存在
router.del('/contact', async ctx => {
	let id = getQueryVariable(ctx.request.url, 'id');
	const res = await del(id);
	ctx.body = {
		code: 200,
		message: '删除成功'
	}
});

router.get('/longtime', async ctx => {
	let query = () => {
		return new Promise((resolve, reject) => {
			setTimeout(function () {
				resolve('请求成功');
			}, 5000)
		})
	}
	let result = await query();
	ctx.body = {
		code: 200,
		message: result
	}
});

//截取上传上来的url中的id
function getQueryVariable(url, variable) {
  //按照问号切割返回一个数组,去数组中的第二个元素
	var query = url.split('?')[1];
  //再按照&符号切割
	var vars = query.split("&");
  //遍历vars中的元素
	for (var i = 0; i < vars.length; i++) {
    //按照等号切割
		var pair = vars[i].split("=");
    //将切割的值与传入的对比,为真则返回这个元素,否则返回false
		if (pair[0] == variable) { return pair[1]; }
	}
	return (false);
}
module.exports = router;
复制代码

8、以上就搭建了一个完美的restful接口了

9、接口:

  • 请求全部数据: GET                 /contactList
  • 添加数据           POST              /contact/new/form    or    /contact/new/json
  • 修改数据           PUT/PATCH     /contact/edit     
  • 删除数据           DELETE           /contact  

10、特此声明:

  • 客户端上传数据若在url中上传时,要在params里面取。如:
http://localhost:5000/users/123
复制代码

在服务端获取则要:

router.post('/users/:id', async => {
	const res = ctx.params.id; //123
});
复制代码
  • 客户端上在的数据以参数形式上传时,要在request.body中获取。如:
http://localhost:5000/users?id=1&name=zs&age=18
复制代码

在服务端获取则要:

router.post('/users', async ctx => {
	const res = ctx.request.query;//这是一个对象
  /**
  *{
  *	id: 1,
      * name: zs,
  *	age: 18
  *}
  */
});
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享