import { JsonController, Post, Body, UseAfter } from "routing-controllers";
import { Service } from "typedi";
import RecordMiddleWare from '../../middlewares/RecordMiddleWare';
import RuleRepository from "./repository";
import { AnyObject } from '../../config/interface';
@Service()
@JsonController('/rule')
export default class RuleController {
@Post("/update")
@UseAfter(RecordMiddleWare)
async update(@Body() body: AnyObject) {
const { id } = body;
const before = await this.ruleRepository.findOne(id);
await this.ruleRepository.update(body);
return { before, after: body, id, update_type: 'rule' };
}
}
总结
这一篇主要讲了koa-spring的一些库应用及项目实现方式,这里不得不强力推广routing-controllers与sequelize-typescript这两个库,Thanks to @RobinBuschmann for answering my issue so patient(maybe you can't understand what i write or say, just accept my thanks)。感叹一句,写Demo和实际应用到业务真的是天差地别,在下一篇,将会谈一些深入的优化和疑难点解决,主要关于:
关于这篇文章
工程搭建
主框架:routing-controllers + Koa
routing-controllers是一个相对于Egg和Nest较小众的库。
迭代较慢,三年时间才到0.8.0的版本,没有官网,只有Readme。但这些丝毫不掩盖其易扩展的品质,routing-controllers的引入,未改变Koa的洋葱模型中间件机制和错误捕获机制,结合Typedi,也能做到Nest框架的效果。下图是自己使用后整理的routing-controllers中间件机制。
全局中间件和路由局部中间件,我觉得设计是十分巧妙的,这对解决通用问题,是及其有效的,在后面的中间件一节会具体分析。官方提供的Demo,也可以下载运行一下试试。
Model:数据库操作:Sequelize
页面接口直接对接数据库,所以希望选择一个类似JPA,Hibernate这样的ORM框架,简化Sql操作,可选项不多,也没做多少对比,最后选择了Sequelize,结合sequelize-typescript,也收获了一个不错的开发体验,下面的代码就是一个日志模型的声明:
下面一段代码就是Sequelize的基本CUR操作,看起也是十分便捷的,这里出现了几个自定义的装饰器,在后面会专门讲到:
Sequelize带给我唯一的困惑就是,其默认返回的响应体,是一个被他的Model类封装过的数据集,说起来有点抽象,看下面的响应实例:
期望响应体
实际响应体:太长,截取部分
看起只需要拿响应体的dataValues就是我们期望的响应体,但这个响应体是相关getter属性方法并没有执行。官方也提供了{ query: { raw: true }}这个设置去获得简单的响应体,但也有同样的问题,getter属性未执行。看了一下官方实现,getter方法是在调用toJson方法时,才会执行(疑惑不解脸)。
中间层服务的处理:
在实现登录,权限,日志,存储作为中间层对接公司的公共服务时,Node需要发起请求,并响应包装转发出去,这里选择了比较成熟的request和request-promise库。
数据校验:
虽然这是一个内部系统,除了前端提交做校验外,业务方还是希望接口层要有一些必要的校验。如果全部用If-else写,想想这还是一个比较大的工作量的,不过还好,有class-validator这个库的存在,加上装饰器的写法,还是比较简洁。比如下面这个登录表单的校验示例:
语言:Typescript
看上面那么多,你应该猜到了,这个项目选择了Typescript。
中间件
在我的项目中涉及到多个中间件,既有全局中间件,比如鉴权,响应体包装,错误处理;又有局部路由中间件,比如操作日志,分页。
全局中间件-鉴权:AuthCheckMiddleWare
routing-controllers提供了鉴权认证机制,但操作起来不方便,需要每个路由去添加标志。所以自己实现了鉴权中间件,全局中间件都继承于KoaMiddlewareInterface,需要区分是路由响应前,还是响应后。鉴权中间件的目的是验证每一个请求,是否有操作权限,验证token的有效性。这里的实现是一种简易的形式,只检查了本地缓存信息,未到用户中心继续验证,供参考:
全局中间件需要在生成koa实例时,进行注册:
局部路由中间件-操作记录:RecordMiddleWare
操作日志中间件,其目的是记录某些表的数据新增,修改操作。需要记录下字段修改前和修改的值,操作类型及操作人。如果按常规思维,在每一个需要记录操作的路由Controller去加入日志记录代码。代码冗余,且日志记录需求变动时,是一件非常被动的事情,所以局部路由中间件是最好的实现方式,在需要记录的路由加入这个中间件即可。
在规则数据更新时,加入操作日志记录中间件
总结
这一篇主要讲了koa-spring的一些库应用及项目实现方式,这里不得不强力推广routing-controllers与sequelize-typescript这两个库,Thanks to @RobinBuschmann for answering my issue so patient(maybe you can't understand what i write or say, just accept my thanks)。感叹一句,写Demo和实际应用到业务真的是天差地别,在下一篇,将会谈一些深入的优化和疑难点解决,主要关于: