瞎扯淡 请教接口设计规范问题

thxagain · 2019年02月15日 · 最后由 zionfuo 回复于 2019年02月21日 · 2360 次阅读

今天看到同事设计的接口(Java):

新增数据和更新数据是同一个接口,仅仅是根据参数不同(新增没有主键 id,更新有 id),在 service 里的逻辑用 if else 区分开来。

他给出的理由是,因为请求参数差不多,service 逻辑中有重合的部分(比如校验参数),返回值也是一样的,所以就放在一起了。

我想问问大家这种设计风格常见么,他说之前呆的公司里都是这么设计的。

他给出的理由是,因为请求参数差不多,service 逻辑中有重合的部分(比如校验参数),返回值也是一样的,所以就放在一起了。

这个理由不太靠谱啊,为什么 service 逻辑中有重合的部分就一定要同一个接口,难道 service 逻辑一定要和接口路由耦合在一起?

adamshen 回复

刚发现他之前提交的代码,新增/更新/删除是同一个 url,名称直接就是 handleXXX,请求参数里有一个 type,感觉 type 来区分具体操作类型

话说我之前也见过别的组也有这样的接口,调用的时候没觉得奇怪,可是自己的工程里出现这种风格的代码,还是觉得怪怪的。

thxagain 回复

那样的话只是把 http verb 放到 params 里,把 id 从 path 移动到 query 里。硬要这样做也不能说有错,只要项目里的人都能够接受这种约定就可以了。估计是他有一套老的代码是这种接口设计的,然后就懒得改了呗。

反正我个人是很讨厌这种设计的。我觉得常规的接口设计应该是和业务相关的,在接口这个粒度上就应该区分不同的业务事件。新增和修改明显是两件不同的事,理应分开。

那你们的系统里没有涉及到权限控制的功能吗?

有的角色不能修改只能新增可咋整

另外。。。真的不考虑 restful 么

楼主为什么只在论坛吐槽,不直接对同事说呢?

“我想问问大家这种设计风格常见么,他说之前呆的公司里都是这么设计的。” 还以为多大点事儿呢,你直觉不喜欢,但是同事已经有实践经验了,何不直接研讨他这样设计会遇到的问题?

nouse 回复

我和他讨论了可能的问题:

可拓展性变差,如果后续新增和编辑的逻辑变化了,可能会导致两种完全不一样的逻辑混合在一个接口里。

但是这个理由他不太接受。

在论坛里不是吐槽,是想大家帮忙想想这么实践不好的地方,或者告诉我,“这种情况就是很正常的,我们公司也是这样”。

tomnia 回复

目前还没有权限控制,不过是一个切入点,可能会存在权限不一样的场景。

有一个考量是日志和监控。

我在负责的项目的现行做法是在应用代码(语言是 Python)里写一个专门的 WSGI 中间件,这个中间件负责把请求耗时和请求的一些元信息(URL path,HTTP method 等)发送到储存服务(目前在用 InfluxDB)。

如果遵守了 REST 设计规范,那么 HTTP method 加上 URL Path(不包括 query string 部分)就足够表达这个请求落在哪个接口。在展示监控数据的 dashboard 上可以按照这些元信息来筛选数据。如果要自己发明约定规则,那么收集 + 储存 + 展示数据的服务都需要对这个约定 aware 才行。换句话说,这些服务都要对"是否包含 id 字段"做区别对待。虽然这个问题自己写代码总能解决,但遵循了 REST 约定就可以享受现成的方案,节省开发者的时间。

如果我想把上述的监控数据收集方案改成用日志收集 agent 来转发负载均衡的访问日志,从而少写代码,进而移植到别的应用 / 服务(很可能不是用同样的编程语言编写的)上去,那么这时遵守一个更流行的规范就能节省更多开发时间。

这种方法是不好的,创建和更新是两个不同的业务逻辑,需要不同的接口,即使处理的代码有很多相似的地方,也不要合成一个。分开的好处是单一职责,和在一起肯定会增加复杂度,另外就是容易扩展,如果以后两个接口处理的逻辑又有不同,就要再加 if-else 判断是 create 还是 update。不过你应该都知道,那就是沟通和说服别人的问题了,这个是最难的,慢慢来。

有什么问题么?没什么问题啊。你用 restful 只是把 type 从 body 里转移到别的位置了。

😄 规范主要是为了风格统一,让后来的人能够更轻易的理解代码,所以一套项目里面只要一套规范就好了,

我感觉肯定要用两个接口,职责不一样。写代码不能为了复用而复用,首先划分清楚每块代码的职责才是最重要的

@5long @nowherekai @lyb124553153 谢谢回复,遵循规范可以避免踩坑😄

我们新的接口已经拆了。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号