【这是我参与更文挑战的第14天,活动详情查看: 更文挑战】
1、先初始化一个koa2的服务端项目,然后安装项目中所需要的依赖模块:
2、分别创建controller、model、routes文件夹,分别对应的是业务逻辑、mongoose的model、路由接口
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,命令:
;-D是开发环境用的依赖、-S是生产环境用的依赖
- 安装完成之后依赖可以package.json中查;-D对应的是devDependencies、-S对应的是dependencies;如:
- 在package.json中将原来的更改为nodemon启动:
- 现在就可以用命令:
启动了,如图就启动成功了:
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