采取 RESTful 风格的 api 是否应该对结果包一层?

2019-10-21 23:18:13 +08:00
 h82258652

RT,今天公司的新项目开始对接,app 端的一看我这接口就吐槽我。让我改成如下这种: { "code": 200, "message": "", "data": xxx }

但我觉得首先这 code 肯定是多余的,可以直接从 http 状态码里面读取。之前也看过 twitter 的 api,也没有说包一层,200 的话那就直接返回 data 了。 公司项目我就忍忍算了,毕竟人家老员工。但后面有自己项目的话,还是想弄标准一点。不知道一般来说,大家是怎样实现?

25766 次点击
所在节点    程序员
305 条回复
qlhai
2019-10-22 10:29:57 +08:00
此处是业务 code,跟 HTTP 那个还是不一样的啊
Narcissu5
2019-10-22 10:30:53 +08:00
@Amayadream
@pkoukk 登录失败和登录失效压根就不是一个场景下的问题
你们就说说你们监控了 code 没有
uxstone
2019-10-22 10:32:36 +08:00
如果是用 Spring 的话,一个注解就能搞定
想多包装一层就加注解,不想包装就不加注解
markgor
2019-10-22 10:35:03 +08:00
@chendy http 的 code 只能代表請求的結果吧?
返回數據裡的 code 是代表業務的執行結果,根本是兩回事,
不要動不動就說別人不懂 http 的 code,只是別人想的比你多一步。

eg:
在線預訂門票的栗子,
對方業務系統規定:
當 code 為 9999 時,代表對方系統維護中,所有請求 30 分鐘後重試。
當 code 為 1XXX 時,違反門票業務約定( XXX3 位數代表著不同的約定)
當 code 為 2000 時,代表著訂單提交成功
當 code 為 3XXX 時,代表處理失敗,違反直連約定,具體根據 XXX3 位代表不同的結果,有可能是重複單號

直連約定上,當 http 服務不可用(返回非 200,需要每隔 5 分鐘進行重試,超出 10 次後線下聯繫處理。)
當返回 9999 時,代表對方系統維護
兩個是不一樣的概念,你為何可以那麼優秀地認為別人是多此一舉呢?如果你用 http 的狀態碼來表示,拍錯的時候不會導致連業務信息處理出錯或 http 請求出錯都區分不了嗎?

另外“类似的道理,还有用参数指定返回格式的人,大概是不知道 Accept 头(可能也不知道 Content-Type”
給個例子你,
甲方對接了很多套酒店系統,有些系統返回的是 xml,有些返回的是 json。
然後乙方和甲方對接,數據返回根據甲方提供的 api 均為 json,
但是由於很多實時請求是乙方 發送請求給甲方 甲方 再發給酒店,(等於甲方做數據交換),
這個時候甲方在返回給乙方的數據架構上,加上數據具體格式,有問題嗎?
response->{
code:2000,
type:'json',
data:'{code:xxxxx,data:xxxxxxxxxxxxxxx}'
}
你肯定會說為什麼甲方不解釋了酒店數據,然後直接返回給乙方。
那是因為甲方是做數據交換服務,在數據改動最少的範圍內傳遞給乙方。
cmobiooo
2019-10-22 10:35:15 +08:00
@icris 我前公司在客户端的 API 里是这么做的……
Narcissu5
2019-10-22 10:37:21 +08:00
@eason1874 撞库或是社会工程学爆破,能不能嗅探到账号是否存在差别就太大了
passerbytiny
2019-10-22 10:37:27 +08:00
@yamedie #75
@pkoukk #81
@Amayadream #86
三位一看就没设计过错误代码,根据登录接口的不同返回情况做不同的后续交互处理,这是登录功能自己的事,并不是全局通用规则,所以这些不同错误情况的代码,应当放到 data 中,而不是 code 中。
reus
2019-10-22 10:38:48 +08:00
@chendy 你大概不知道以前有 http 劫持,http 状态码不是 200 就直接给你“智能”处理了。当然现在普遍 https,很难劫持了。所以接口不依赖 http 状态码,是有历史原因的,并不是别人不知道。
ClericPy
2019-10-22 10:40:41 +08:00
第一句就提到是对接了, 说明对已有项目规范不了解, 先去看一下公司 API 设计文档吧, 谁知道 code 说的是什么 code, 有问题最好当面提出来, 跑这里吐槽只会恶心自己, 有些前端就是需要详细 code 来判断操作结果, 上面某人说的 99% 也不知道从哪搞来的多大的样本

上面还有一大群说 status code 用来分析日志更方便, 难道不知道日志系统里, access 日志和 server 日志不是同一个用途的吗, 后者自定义日志用来分析的, 前者也不是用来看这个的, 自己公司不用不等于别的公司用不着, 还是具体问题具体分析吧, 简单地说, API 规范这东西和产品经理多问问, 免得写出来给你砍掉

细分错误码, 甚至正确的返回码, 方便调试也提高用户体验, 很多时候用户不关心, 但是调试关心, 类似微信公众号错误码 (虽然他们家的也不咋滴)
https://iot.weixin.qq.com/wiki/document-2_14.html
==============================
错误码 错误信息 描述
0 ok 成功
-1 system error 系统错误
100001 not exist 查询请求不存在
==============================
haha370104
2019-10-22 10:46:02 +08:00
只有一个问题,也不是杠

比如有个接口在查询不到数据报错的时候,直接用 httpcode 404 报错?

那前端监控应该怎么加呢? 4xx 错误有的是预期错误(比如账号不存在)有的可能是非预期错误(比如手抖或者 server 问题真的 url 404 )
miniwade514
2019-10-22 10:46:28 +08:00
@reus 不用大概,是肯定不知道。然而他不去了解就说别人蠢,前途无量。
reus
2019-10-22 10:46:32 +08:00
另外,如果需要在非 http 承载调用,例如直接 tcp 或者其他 rpc 框架,那还是需要信封的。如果已经有信封,那不需要改动就能迁移,调用端也能无缝兼容。

不要太过依赖 http,世上并不是只有 http
losephsky
2019-10-22 10:47:56 +08:00
支持业务 code
reus
2019-10-22 10:48:03 +08:00
@miniwade514 年轻人不知道一些旧事,可以原谅…
markgor
2019-10-22 10:51:23 +08:00
@Narcissu5 我看你說的,側重點在於監控方面吧?
我之前對結果其中一家數據交換公司,他們 PM 每月都會發送一份報表給我們,
其中包括 接口請求成功率,接口預定成功率
接口請求成功率 是他們考量他們自身服務的標準,其中包含簽約時候的 sla。
接口預定成功率 這個是考量他們系統和酒店系統的服務標準。
實際上除了這兩份報表外,還有其餘很多報表,大致是分析推送數據成功率,延遲等等。

你說 response 返回多一層 code 無法監控,
那請問別人為何又能監控,而你無法監控?
index90
2019-10-22 10:56:00 +08:00
每次有人在纠结返回码问题的时候,我就贴出这个链接,然而每次都没有人看。
https://cloud.google.com/apis/design/errors

Google APIs must use the canonical error codes defined by google.rpc.Code. Individual APIs should avoid defining additional error codes, since developers are very unlikely to write logic to handle a large number of error codes. For reference, handling an average of 3 error codes per API call would mean most application logic would just be for error handling, which would not be a good developer experience.

试想想,如果下游服务返回一个错误码给你,你有两个选择
1. 识别并处理这错误码:
if code == some_error_code {
// do something
}
2. 不处理透传返回码:
if code != 0 {
return code
}

第一种,如果你错误码很多,那你就要写大量的错误码处理逻辑(每个接口)
第二种,透传到上层,那上层遇到的错误码可能性就越多,越不想处理。那么错误码的意义在哪里?出错是,方便定位?那一个字符串类型的 error detail 是不是表达能力更强?
Amayadream
2019-10-22 10:56:52 +08:00
@Narcissu5 #102
核心业务都需要做错误码监控和告警的,不熟悉可以去了解一下。

@passerbytiny #107
我觉得你可能没出校门。
star7th
2019-10-22 10:59:04 +08:00
没法看了,这种做多几个项目就能明白的事情为什么会引起这么多争议。
因为偶尔情况下,前端或者 app 需要根据状态吗来做业务逻辑处理啊。http code 是系统层面的,代表请求本身成功,不应该跟具体业务耦合。
比如说,获取用户资料信息,万一用户在获取的时候 token 过期呢,前端就可以根据返回状态吗引导用户重新登录。
这样做固然并不是绝对的需要,但很明显这样包一层更方面以后传递信息和自定义更多异常处理。
Narcissu5
2019-10-22 11:00:12 +08:00
@markgor 不是无法监控,而是成本非常高

如果你有了解过 Http 协议的话就会明白,分析 Http Header 很容易,而分析 Http body 是很耗时的,实际上对于简单的应用来说,相当一部分的 CPU 时间用在了序列化 /反序列化上。如果你的接口支持通过 Accept 指定不同格式的返回消息那问题就更加复杂得没边了
maomaomao001
2019-10-22 11:00:27 +08:00
@helone 举个最简单了例子,
比如业务就是, 登录的时候,账号错误 focus 到账号输入框并变红,密码错误 focus 到密码输入框并变红(虽然现在不会单独搞这种错误了) , 你只给个信息不够呀,是不是还得有标志位???

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/611572

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX