今天看到同事设计的接口(Java):
新增数据和更新数据是同一个接口,仅仅是根据参数不同(新增没有主键 id,更新有 id),在 service 里的逻辑用 if else 区分开来。
他给出的理由是,因为请求参数差不多,service 逻辑中有重合的部分(比如校验参数),返回值也是一样的,所以就放在一起了。
我想问问大家这种设计风格常见么,他说之前呆的公司里都是这么设计的。
他给出的理由是,因为请求参数差不多,service 逻辑中有重合的部分(比如校验参数),返回值也是一样的,所以就放在一起了。
这个理由不太靠谱啊,为什么 service 逻辑中有重合的部分就一定要同一个接口,难道 service 逻辑一定要和接口路由耦合在一起?
刚发现他之前提交的代码,新增/更新/删除是同一个 url,名称直接就是 handleXXX,请求参数里有一个 type,感觉 type 来区分具体操作类型
话说我之前也见过别的组也有这样的接口,调用的时候没觉得奇怪,可是自己的工程里出现这种风格的代码,还是觉得怪怪的。
那样的话只是把 http verb 放到 params 里,把 id 从 path 移动到 query 里。硬要这样做也不能说有错,只要项目里的人都能够接受这种约定就可以了。估计是他有一套老的代码是这种接口设计的,然后就懒得改了呗。
反正我个人是很讨厌这种设计的。我觉得常规的接口设计应该是和业务相关的,在接口这个粒度上就应该区分不同的业务事件。新增和修改明显是两件不同的事,理应分开。
楼主为什么只在论坛吐槽,不直接对同事说呢?
“我想问问大家这种设计风格常见么,他说之前呆的公司里都是这么设计的。” 还以为多大点事儿呢,你直觉不喜欢,但是同事已经有实践经验了,何不直接研讨他这样设计会遇到的问题?
我和他讨论了可能的问题:
可拓展性变差,如果后续新增和编辑的逻辑变化了,可能会导致两种完全不一样的逻辑混合在一个接口里。
但是这个理由他不太接受。
在论坛里不是吐槽,是想大家帮忙想想这么实践不好的地方,或者告诉我,“这种情况就是很正常的,我们公司也是这样”。
有一个考量是日志和监控。
我在负责的项目的现行做法是在应用代码(语言是 Python)里写一个专门的 WSGI 中间件,这个中间件负责把请求耗时和请求的一些元信息(URL path,HTTP method 等)发送到储存服务(目前在用 InfluxDB)。
如果遵守了 REST 设计规范,那么 HTTP method 加上 URL Path(不包括 query string 部分)就足够表达这个请求落在哪个接口。在展示监控数据的 dashboard 上可以按照这些元信息来筛选数据。如果要自己发明约定规则,那么收集 + 储存 + 展示数据的服务都需要对这个约定 aware 才行。换句话说,这些服务都要对"是否包含 id 字段"做区别对待。虽然这个问题自己写代码总能解决,但遵循了 REST 约定就可以享受现成的方案,节省开发者的时间。
如果我想把上述的监控数据收集方案改成用日志收集 agent 来转发负载均衡的访问日志,从而少写代码,进而移植到别的应用 / 服务(很可能不是用同样的编程语言编写的)上去,那么这时遵守一个更流行的规范就能节省更多开发时间。
这种方法是不好的,创建和更新是两个不同的业务逻辑,需要不同的接口,即使处理的代码有很多相似的地方,也不要合成一个。分开的好处是单一职责,和在一起肯定会增加复杂度,另外就是容易扩展,如果以后两个接口处理的逻辑又有不同,就要再加 if-else 判断是 create 还是 update。不过你应该都知道,那就是沟通和说服别人的问题了,这个是最难的,慢慢来。