API 不管操作成功还是失败都返回 200 状态码,自己在返回结果里又定义一个表示是否成功的属性是从哪里传开的坏习惯?

2022-12-03 21:22:25 +08:00
 edis0n0
一直以为是从阿里开始传到整个中国互联网企业的坏习惯,最近发现一些日本网站也都这样做。但欧美网站大部分不这样做,例如 stripe ( https://stripe.com/docs/api/errors) twitter 等,都是规范的使用 http 状态码表示操作成功或失败,但 google 一些没有公开文档的私有 api 返回状态也非常混乱
7555 次点击
所在节点    程序员
92 条回复
iseki
2022-12-03 23:37:21 +08:00
时至今日 HTTPS 已成基本前提,大多数场景不需要再考虑劫持这种稀奇古怪的事情了,为了规避劫持改变系统设计有些得不偿失
fkdog
2022-12-03 23:38:53 +08:00
如果我把业务 code 全都封装进 http entity 里,那么有个好处就是哪天我要把 http 替换成自定义的 rpc 协议,对接方可以用最小的代价来做调整,而不是一行行去找对应的 http status code 。

你们平时玩 clash/gost 不都是这样吗?把传输协议和具体的代理协议给解耦开来,可以方便随意组合配对。哪天 ss 协议要是可以配上 https ,有人非要 ss 协议密码不对的时候返回 http status 403 ,这样才 restful ,你们会不会觉得有病??

国内这种普遍把业务 code 塞进 http entity 里实际上也是一种不错的设计,纯粹把 http 当成是传输协议。300/400/500 这些用来辅助运维排查问题,对接方只管 status==200 或 400 的。

把 restful 奉为圭臬的通通有点猫饼。当然这一切还是要以公司规范为前提,如果规范是 restful 的那么就按照 restful 来,如果规定业务 code 写进 body 的,那就写进 body 。
AyaseEri
2022-12-03 23:44:06 +08:00
这问题不一定是个技术癖好问题,也可能是个多团队协作、多系统调用、研发运维体系、基建建设与封装等管理问题。
shakukansp
2022-12-03 23:58:32 +08:00
@edis0n0 nginx 或者 api 网关也会有些默认的返回错误 http 状态码行为,混在一起排查问题的时候会受苦
xy90321
2022-12-04 00:03:55 +08:00
@edis0n0
200 以外返回内容不一定是 API 给出来的
敢情聊了那么多楼都白聊了呗…
如果你所处的业务环境简单到不需要区分网络协议状态和业务状态,那随便怎么搞都可以
但是也请理解有更多业务环境比这复杂的多
shakukansp
2022-12-04 00:05:21 +08:00
@edis0n0 换句话说,200 中的错误代码即代表这个 http 请求必然成功通过了 nginx api 网关到达了后端
错误必然是由后端服务返回的
在后端查看日志极其麻烦的情况下有助于快速定位问题出在哪里
pengtdyd
2022-12-04 00:12:51 +08:00
我觉的这里应该要区分业务状态码和 http 状态码吧。

200 、500 、404 等这些是 http 状态码,它反映是请求和响应情况的状态
00000 、A1000 、B2000 等这些是业务状态码,它反映的是业务执行情况的状态

举例:404 表示这次请求没有找到资源,如果业务执行失败返回 404 ,这根本说不通,这里有歧义:到底是请求本身失败了,还是业务执行失败了。
Dragonphy
2022-12-04 00:13:43 +08:00
日经贴……
edis0n0
2022-12-04 00:17:01 +08:00
@xy90321 #45 照你这么说 200 状态也不一定是 API 给出来的啊,配置错了反代的时候 200 状态的 API 也有可能被缓存
thisIsDing
2022-12-04 00:21:09 +08:00
遵循 restful 的规范,同时在业务异常的时候加上类似 Error-Source: business 的响应头来标识异常的来源和格式。网关发生异常也可以复用这个头,只要设一个不同的值来区分就好。总之我们是这么做的。
flyqie
2022-12-04 00:34:47 +08:00
个人倾向于使用 200 + post + json ,不支持采用 http status code 来同时判断业务和协议的做法。

1. 与 http 协议耦合度较高
2. 不利于错误码拆分
3. 不利于排查,无法直观查看到底是业务还是基础设施问题。
4. 兼容性较差,楼上不考虑兼容性问题的是没被坑过吗。。有些玩意不是你能决定的,遇上了那就算是倒霉,现改业务代码和网关麻烦的要死。
edis0n0
2022-12-04 00:37:00 +08:00
@flyqie 那为什么 stripe twitter 这些国外平台都是用 HTTP 状态码区分错误呢
dcsuibian
2022-12-04 00:39:11 +08:00
为什么国外的就是好的呢?
flyqie
2022-12-04 01:05:07 +08:00
@edis0n0 #52

将技术方案绑定到平台来做比较其实是不太合理的。

1. 不同公司基础设施架构是不一样的。
2. 某些时候技术方案不一定是靠全局优势,还可能仅靠个人喜好或业务优势而被采用。
3.兼容性是根据业务而变的,如果已经完全确认不需要,那当然可以抛弃掉无用的那些兼容性。

归根到底,这其实并不是一个纯技术问题,跟业务和人有分不开的关系。

就从我自己开发中得出的经验来看,200 + post + json 是在大陆(港澳台没深入了解过)普通项目中最有兼容性也最省事的方案,但具体落实哪个还得看实际。
binux
2022-12-04 01:09:34 +08:00
我一直说,200 一把抓是因为能力不足,无法正确地控制使用上下游组件和框架而偷懒的行为。
chenxiankong
2022-12-04 01:20:50 +08:00
对 http 状态码,个人看法就是 2xx+非 2xx+业务状态码.错误异常拆分很方便,也不受协议限制.
公司内使用 http 状态码的太多意义反而会提高系统复杂度.怎么方便怎么来.
xy90321
2022-12-04 01:57:48 +08:00
@edis0n0
对呀 那你还那么钟情于 http status code 干啥咧
iseki
2022-12-04 02:40:02 +08:00
不存在什么业务异常、系统异常;业务上的冲突,是客户端发起的请求引起的,比如余额不足、用户名冲突等等,4XX ;服务端的异常,比如数据库无法连接、资源不足等等属于故障,5XX
eason1874
2022-12-04 03:30:51 +08:00
我常跟行家讲,把 HTTP 当传输层协议,状态码不必自己改,拿过来先返回 200 ,接下来 JSON 打包响应体,两转三转,四五六七八转,层层解码层层编码,再下来跟运维打架,让他们自己解包取状态码做监控,这个工程下来,你摸鱼时间起码占一半
xuanbg
2022-12-04 09:21:25 +08:00
@edis0n0 你认为应该使用 http status 表示请求的状态没错,但事实上,你的请求仅仅是一个原始的 http 请求吗?返回的数据是一个 html 文件吗?显然不是,你这个 http 请求返回的数据除了没有 html 文件,什么样的数据对象都有。因为返回的不是 html 文件,所以,你更应该关注的不是 http 协议的 status ,而是其内含的业务逻辑。http 协议只是用来承载数据的,一般我们都不会关注它的状态,他的状态就应该是 200 ,不然,肯定是网络数据链路发生了故障。

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

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

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

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

© 2021 V2EX