这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战
1. 前言
今天聊聊我们接触最多的接口,主要是聊接口上的出入参,有的同学就说了,啊不就是接口入参吗,有什么好聊的,大家不都这样用吗,都成规范了;但是所写,都是我在实习公司听到的、见到的一些”现实“
其实聊这个问题,就是希望一些新入行的同学也好,还是外包行业的一些”老油子“也好,我们不得不承认,有些时候我们正在生产难以维护的代码。
虽然这个难以维护是相对的,假如这个项目写出来后,就不再需要任何的维护,不会再有任何的改动,那理论上随你怎么写,因为不会有人再去看这段代码;但是现实中真的有这种情况吗,哪怕有,我相信也很少
2. 使用 Map 作为入参的现象
当我入职的时候,第一个任务是熟悉项目,在我一顿操作后,打开代码,发现接口层出现大量的这种代码:
@PostMapping("/addProject")
public Map addProject(Map map) {
//对某个参数进行校验
if (map.get("id") == null) {
throw new Exception();
}
//使用faster json将map转为对象
Project project = ObjectUtil.ConvertMapToBean(map);
//经过service处理后再返回Map给前端
Map result = projectService.add(project);
return result;
}
别的不说先,这里首先就有几个很明显的问题:
- 难以维护:接口入参使用了 Map 进行封装,如果没有接口文档,维护的人很难知道到底传的是什么参数进来,直接进行调试也变成了不可能
- 参数校验又长又臭:需要手动对进行参数校验,假如需要校验的参数特别多,那这个参数校验是不是要写特别的长?
- 低效:每一次入参都是用了
FasterJson
进行转换,这样大大降低了接口的效率,特别是 QPS 高的时候 - 空指针异常:容易造成空指针异常,当我们代码中需要用到的参数去 Map 里获取,假如参数校验没做好,且入参的时候没有传,就会出现空指针异常
当我带着这些问题找到项目的负责人,一开始我认为会是一场讨论,然而我得到的回复是:”这样开发是有好处的,这大大减轻了后端开发的难度,让我们用更少的代码,更少的时间可以把这个事情做好!“
所谓道不同不相为谋,既然项目负责人坚持这么用,那就可以说得通为什么代码里面到处都是这种风格,甚至为了解决使用 Map 而出现的问题封装了一堆解决这些问题的工具类。
带着这些问题我又继续深入学习,一段时间后,我果然的发现,他们是没有接口文档的,不是他们不想用 Swagger,是因为 Map 的封装导致 Swagger 根本无法使用,并且出 Bug 的概率也是相当的高
3. 为何还有人坚持这么做
在我的理解来看,有三种可能:
- 项目负责人追求快速的完成工作,而不追求质量,特别是外包性质的工作,乙方只管完成合同把代码给你,至于维护性什么的,谁理呢?
- 开发项目的同事在初学时,遇到了第一种情况的导师,认为这种情况是理所当然的,长年累积,不愿意改,也不想改,于是又变成了第一种人
- ”老油子“,你们怎么用,我就怎么用,改变什么的,不存在的,团队的风格就是我的风格
4. 现在我们怎么做
看完了反面教材,我们来看看现在大部分人怎么做:
@PostMapping("/students")
public Response<Student> insert(@RequestBody @Validated Student student) {
return success(studentService.save(student));
}
现在的一个业务接口,可能就是这么简单明了,让我们来看看这里都包含了什么信息:
- 遵从 RestFul 风格的 API,使用 Post 来进行保存操作
- 封装了同一的返回对象
Response<Student>
,返回的格式是统一的,让前端可以封装统一的接收格式 - 使用了
@RequsetBody
+ 实体类对象来接收 Json 格式的参数,传了什么一目了然
再来说说这样做的好处:
- 参数校验:接口入参中,添加了
@Validated
注解,只要在Student
类中添加对应的参数校验注解,就可以对入参进行自动校验,不合规的参数直接返回错误信息 - 一目了然:什么进来了,什么出去了,维护者一目了然
- 目的清晰:熟悉 RestFul 的人一看,基本就能知道你这个接口要做什么
- 接口文档:同样的,这种接口可以引入 Swagger 等自动化接口文档工具,可以在开发的时候花一点点时间就把接口文档写好,同时更新的时候也只需要该少量的代码
5. 写在最后
随着技术、项目的迭代,也许这种现象会越来越少直至消失,但是我想要表达的思想是:
- 当我们遇到技术时,不能盲目的使用,而是要横向对比,你得明白,他能干什么,不能干什么,给未来的自己留一条退路
- 也许你不得已在做错的事情,但是你要明白你做的事情是错的,并且努力修正这个错误,比如做好注释
- 努力用技术武装自己,哪怕你只是在这个行业呆一段时间,也请你有基本的职业道德,尽量不给后人埋坑