第三章 从数据库中获取数据并返回给API接口
上面,我们已经通过路由成功将内容返回给了api接口,但是数据都是动态的,后端是用于连接客户端和数据库并完成逻辑的一端,显然需要从数据库获取数据返回给api接口
这里我们使用的数据库是Mongo,桌面客户端推荐robo mongo
tips:
使用docker安装mongo
mongo的使用方法
安装好mongo数据库后,使用robo mongo连数据库
点击右键创建一个新的数据库,命名为library
右键创建数据表,命名为book
为book表添加几条数据
db.getCollection('book').insertMany([
{
name: '瓦尔登湖',
author: '梭罗',
createdAt: new Date(),
createdBy: 'default'
},
{
name: '挪威的森林',
author: '村上春树',
createdAt: new Date(),
createdBy: 'default'
},
{
name: '三体',
author: '刘慈欣',
createdAt: new Date(),
createdBy: 'default'
}
])
点击绿色箭头或者ctrl + enter执行语句创建三条数据
添加好数据之后,我们就可以写代码获取这些数据了。
首先我们使用mongoose这个包来操作mongo数据库,那么我们先装上这个包
npm install mongoose --save
然后在入口文件引用并连接数据库
src/server.js
const Koa = require('koa');
const app = new Koa();
const router = require('./router');
// 引入mongoose
const mongoose = require('mongoose');
// 使用mongoose连接数据库,mongoodb:// + mongo host + mongo port + 数据库名字,在本地启用的mongo我们直接使用localhost,默认端口是27017,数据库名称就是刚才我们创建数据库的时候取的名字
mongoose.connect(`mongodb://localhost:27017/library`, { useNewUrlParser: true });
app
.use(router.routes())
.use(router.allowedMethods())
app.listen(3000);
console.log('Web server run on port 3000');
tips:mongoose使用文档
之前我们在路由文件src/router.js中实现了接口返回的方法,不过通常,为了使得项目的结构更加整洁,能够一目了然的看清楚一个文件大致实现的是什么类别的功能,我们是不会将过多的功能聚集在某个文件下的。因此,src/router.js只实现路由,真正的方法我们会创建新的结构层在实现。
我们把router文件修改一下,创建一个新的路由,用以获取书本数据
src/router.js
const Router = require('koa-router');
const router = new Router();
// 引入一个新的文件,这个文件就是用来将原来的路由接续的函数分开到另一个文件夹的controller层
const { BookController } = require('./controllers/book-controller');
router.get('/', ctx => ctx.body = 'Web API Running Successfully.');
// 这里,第二个参数原本是一个函数,这里我们将它拆分到controller层中
router.get('/api/books', BookController.get);
module.exports = router;
然后在src创建文件夹controllers,并创建book-controller.js
controller层,用于接收路由的的参数,并将起传给services层(用于组织逻辑)后将其结果返回给api接口的层。也就是说controller层主要起到一个api的调配控制的作用。
src/controllers/book-controller.js
// 引入service层的BookService
const { BookService } = require('../services/book-service');
// 创建一个class,把相关的函数组织起来
class BookController {
// controller层我们使用static函数,静态函数是纯函数,没有状态。也使得在使用的时候不需要new即可直接使用
// ctx是koa框架用户传输相关参数和返回的一个变量,这次我们获取的是全部书本的内容,没有入参,所以不需要组织
static async get(ctx) {
// 将之前引入的service实例化
const bookService = new BookService();
// 使用get方法获取数据
const res = await bookService.get();
// 使用ctx.body将获取到的数据返回给api接口
ctx.body = res;
}
}
module.exports = { BookController };
在src中穿件文件夹services,并创建book-service.js
service层,用于操作数据库并组织相关逻辑,将api所需要的数据返回给controller层。主要的逻辑都在service层中实现。
在写book-service的逻辑之前,还记得我们刚才给数据库已经添加好了数据,我们需要先把数据表的模型建好
刚才我们在数据表books中创建了数据,那么同样的,我们需要在代码中将数据表的数据结构的schema创建出来。
创建 schemas/book-schema.js
const mongoose = require('mongoose');
// 创建一个schema,将数据表的数据结构写进入,我为book表设计了名称/作者/创建时间/创建者/更新时间/更新者等结构
const schema = new mongoose.Schema({
name: String,
author: String,
createdAt: Date,
createdBy: String,
updatedAt: Date,
updatedBy: String,
});
// 创建model,第一个参数是model名称,第二个是上面创建的schema,第三个是数据表名称
module.exports = mongoose.model('book', schema, 'book');
然后是book-service
src/services/book-service.js
// 引入book表模型
const bookModel = require('../schemas/book-schema');
// 创建class,其下是book相关逻辑函数
class BookService {
async get() {
// bookModel为book表,find方法查找数据
const res = await bookModel.find({});
// 将查找到的数据返回给controller
return res;
}
}
module.exports = { BookService };
好了,代码我们就完成了,将程序启动
node src/server.js
来到浏览器,还记得我们的api地址吗:http://localhost:3000/api/books
我们刚才添加到数据库的数据就出现在浏览器了
本文已完成电子书《Node零基础入门到服务端程序》电子书(含教程内项目代码)/ 10元,购买链接:https://mianbaoduo.com/o/bread/mbd-Z5WZk5o=
ps:前九章(本书共计十三章)内容会在这里陆续更新。