喧闹任其喧闹,自由我自为之。我自风情万种,与世无争。
别人对你的打分,是他对你的看法他不了解你的时候,你又何必在乎她的打分呢!你给自己打几分?
上一节,我们搭建了项目,并且完成了项目搭建,【Vue + Koa 前后端分离项目实战】使用开源框架==>快速搭建后台管理系统 -- part1 项目搭建_小白Rachel的博客-CSDN博客
这节我们从后端入手,开始项目代码学习。从后端入手,完成【新增期刊】功能
项目最终实现效果:/island
本节实现效果速览:
目录
一、准备工作
1.功能开发的顺序?
2.代码写在哪里?
(1)项目目录结构
(2)代码规范
(3)数据库模型规范
二、接口开发初体验
1.测试接口编写
2.使用postman工具测试接口
三、【正式开始】接口实现业务逻辑
1.参数校验--校验器
2.执行业务逻辑
(1)新增服务层Service文件
(2)新建模型层Model文件
(3)新增Dao层文件
(4)完整实现Service逻辑
3.完整实现api逻辑
一、准备工作
使用IDE工具打开后端代码lin-cms-koa
koa 是一个优美的微框架,【林间有风】团队自己整理出了开发规范。
1.功能开发的顺序?
先开发后端接口--->再写前端代码-->前后端联调
2.代码写在哪里?
项目文档地址:项目结构及开发规范 | Lin CMS
(1)项目目录结构
(2)代码规范
在app/api
文件夹中开发 API,并将不同版本,不同类型的 API 分开,如:v1 代表 第一版本的 API,v2 代表第二版本,cms 代表属于 cms 的 API。将程序的配置文件放在app/config
文件夹下,并着重区分secure(安全性配置)
和setting(普通性配置)
。配置更详细内容参考配置将可重用的类库放在app/lib
文件夹下。将数据模型放在app/model
文件夹下。将开发的插件放在app/plugin
文件夹下。将校验类放在app/validator
文件夹下。(3)数据库模型规范
koa 本身并非对数据库做出支持,Lin 通过集成sequelize
这个orm 库来进行数据访问, 如果你不熟悉,请先阅读官方文档
中文文档:GitHub - demopark/sequelize-docs-Zh-CN at v5
二、接口开发初体验
1.测试接口编写
在app-->api-->v1目录下新建content.js文件
(1)实例化接口对象
说明:LinRouter()这个类是对KoaRouter的封装,让他的功能更加强大,同时兼容KoaRouter的所有操作
(2)配置路由前缀
(3)定义方法并返回测试数据
// 文件 app/api/v1/content.jsimport { LinRouter } from 'lin-mizar'const contentApi = new LinRouter({prefix: '/v1/content' // 配置路由前缀})// 定义方法contentApi.post('/', async ctx => {const test = {res: true} return ctx.json(test) // 返回测试信息})module.exports = { contentApi } // 导出
2.使用postman工具测试接口
使用node index.js启动项目
由于前端项目还没有实现,之能通过接口测试工具,如postman进行测试
可以看到输入信息,证明接口现在已经跑通了。
三、【正式开始】接口实现业务逻辑
一般写新增接口的业务逻辑:
参数校验执行业务逻辑插入数据库返回成功
1.参数校验--校验器
lin-cms已经内置了参数校验的类库
按照目录规范: 在app-->validators 新建content.js 保持同名
声明 AddContentValidator()类,继承了LinValidator()验证器基类
lin-cms是基于validator.js库实现的。因此validator.js中的原生校验也可以在此使用。
// 文件 app/validator/content.jsimport { config, LinValidator } from 'lin-mizar'import { Rule } from 'lin-mizar/lin'class AddContentValidator extends LinValidator {constructor () {super();this.image = [new Rule('isNotEmpty', '内容封面不能为空')]this.type = [new Rule('isNotEmpty', '内容类型不能为空'),new Rule('isInt', '内容类型id必须是数字')]this.title = [new Rule('isNotEmpty', '内容标题不能为空')]this.content = [new Rule('isNotEmpty', '内容介绍不能为空')]this.url = [new Rule('isOptional'),new Rule('isURL', '内容外链必须是合法url地址')]this.pubdata = [new Rule('isNotEmpty', '发布不能为空'),new Rule('isISO8601', '发布日期格式不正确')]this.status = [new Rule('isNotEmpty', '内容有效状态未指定'),new Rule('isInt', '内容有效状态标识不正确')]}}export { AddContentValidator }
在content中添加如下,进行测试。
// app/api/v1/content.js// 1.参数校验const v = await new AddContentValidator().validate(ctx)return ctx.json(v)
修改完成之后,重启框架。到postman测试
由于没有传参 因此所有的校验都报错。传入一些信息之后,可以校验。
如果想要获取到返回数据,只需要 修改 return ctx.json(v.get('body')) 重启框架,输入正确的信息,可以看到数据已经全部返回。
2.执行业务逻辑
由于movie music sentence三者主要字段相同,但是music多了一个url字段
因此,每次添加之前,需要判断数据是三者之中的哪一类,然后再插入数据库中。
(1)新增服务层Service文件
在app目录下新建service文件,表示服务层文件。并添加centent.js文件。
在类中定义添加期刊的方法addContent,其参数是前端传入的表单。
在switch中判断type字段(100-电影 200-音乐300-句子)插入到表中
import { MovieDao } from '../dao/movie';import { MusicDao } from '../dao/music';import { SentenceDao } from '../dao/sentence';import { NotFound } from 'lin-mizar';class Content {static async addContent (v) {// 根据不同种类判断数据switch (v['type']) {case 100:// 电影// delete v['url']// await MovieDao.addMovice(v);break;case 200:// 音乐/// await MusicDao.addMusic(v);break;case 300:// 句子// delete v['url']// await SentenceDao.addSentence(v);break;default:throw new NotFound({ msg: '内容类型不存在' });}}}export { Content as ContentService };
问题来了:如何插入数据到数据库中?
回答:数据库模型orm库
(2)新建模型层Model文件
在app-->model中新增三个模型文件movie.js music.js sentence.js
每一个模型对应一张表。
import { Sequelize, Model } from 'sequelize';import sequelize from '../libs/db';import { config } from 'lin-mizar';class Movie extends Model {}Movie.init ({id: {type: Sequelize.INTEGER,primaryKey: true,autoIncrement: true},image: {type: Sequelize.STRING(64)},content: {type: Sequelize.STRING(300),allowNull: true},pubdate: {type: Sequelize.INTEGER,allowNull: true},fav_nums: {type: Sequelize.INTEGER,defaultValue: 0},title: {type: Sequelize.STRING(50)},type: {type: Sequelize.INTEGER},status: {type: Sequelize.INTEGER}},{// 定义表名tableName: 'movie',// 定义模型名modelName: 'movie',// 删除paranoid: true,// 自动写入时间timestamps: true,// 重命名时间字段createdAt: 'created_at',updatedAt: 'updated_at',deletedAt: 'deleted_at',sequelize})export { Movie as MovieModel }
定义了一个类,继承Model基类。并配置属性,是关系的映射。
(3)新增Dao层文件
在Dao文件夹下新建三个js文件 movie.js music.js sentence.js 分别对应三个模型
思路:在Dao层中调用模型层
import { MovieModel } from '../models/movie';// 在Dao层中调用模型层class Movie {static async addMovice (v) {return await MovieModel.create(v)}}export { Movie as MovieDao }
(4)完整实现Service逻辑
在service层中,可以调用Dao层数据
service层中的content.js完成整个添加逻辑
由于电影和句子没有url字段,因此去掉即可
import { MovieDao } from '../dao/movie';import { MusicDao } from '../dao/music';import { SentenceDao } from '../dao/sentence';import { NotFound } from 'lin-mizar';class Content {static async addContent (v) {// 根据不同种类判断数据switch (v['type']) {case 100:// 电影delete v['url']await MovieDao.addMovice(v);break;case 200:// 音乐await MusicDao.addMusic(v);break;case 300:// 句子delete v['url']await SentenceDao.addSentence(v);break;default:throw new NotFound({ msg: '内容类型不存在' });}}}export { Content as ContentService };
3.完整实现api逻辑
回到api文件中,完善content.js
contentApi.post('/', async ctx => {// 1.参数校验const v = await new AddContentValidator().validate(ctx)// return ctx.json(v.get('body'))// 2.执行业务逻辑// 3.插入数据库-封装在service层await ContentService.addContent(v.get('body'))// 4.返回成功ctx.success({msg: '期刊内容新增成功'})})
在postman中,模拟数据调用,调用完成之后,直接查看数据库,即可看到新增数据。切换类型,可以测试其他类型的数据新增情况。
至此,我们本节完成了一次新增方法的后端逻辑
问题:每次查看都需要在数据库中查阅数据新增情况,有些麻烦。
因此下一节,我们将 实现 【期刊列表查询】功能
【Vue + Koa 前后端分离项目实战】使用开源框架==>快速搭建后台管理系统 -- part2 后端新增期刊功能实现
如果觉得《【Vue + Koa 前后端分离项目实战】使用开源框架==>快速搭建后台管理系统 -- par》对你有帮助,请点赞、收藏,并留下你的观点哦!