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

2022-12-03 21:22:25 +08:00
 edis0n0
一直以为是从阿里开始传到整个中国互联网企业的坏习惯,最近发现一些日本网站也都这样做。但欧美网站大部分不这样做,例如 stripe ( https://stripe.com/docs/api/errors) twitter 等,都是规范的使用 http 状态码表示操作成功或失败,但 google 一些没有公开文档的私有 api 返回状态也非常混乱
7457 次点击
所在节点    程序员
92 条回复
swulling
2022-12-03 21:25:23 +08:00
其实也说得通,这种情况就是把 HTTP 当作传输层。类似于 rpc over http 。
swulling
2022-12-03 21:27:09 +08:00
阿里的 API 是因为内部之前都是 rpc 接口,对外暴露的 HTTP 接口大部分是网关自动转换的。为了避免错误码映射的复杂性,干脆全 200+POST 最简单。
echo1937
2022-12-03 21:29:27 +08:00
我不赞成 HTTP 状态码来代替业务状态码,前者实在覆盖不了后者,
但是我也很难支持“一个 200 打天下”,直接废掉了 HTTP 状态码这种有广大共识的东西。
mlhadoop
2022-12-03 21:30:30 +08:00
所以最佳实战是怎样的呢?
swulling
2022-12-03 21:32:30 +08:00
@mlhadoop 我以为的人最佳实践是:

要么全 restful ,要么 200+POST 。不要搞中间派不伦不类。
edis0n0
2022-12-03 21:33:13 +08:00
@echo1937 #3 但我认为把原始返回全额外封装一层 code: int, data?: object, error?: ErrorDetail 又不方便又浪费资源 欢迎 v 友反驳但要有根据
Opportunity
2022-12-03 21:34:32 +08:00
HTTP 时代的遗留吧,4XX 状态码可能会被代理服务器改内容
edis0n0
2022-12-03 21:36:20 +08:00
@mlhadoop #4 关于哪种比较好的讨论是 v 站月经了,我想问的是这种习惯是从哪里传开的
xy90321
2022-12-03 21:36:34 +08:00
http status code 反映的是 uri 资源的状态
因此对于一个资源,你是否有权访问 uri 资源跟访问到这个资源后资源内部业务逻辑上的鉴权结果是两码事
所以在我看来,你被 http 服务器权限拦截了返回 http status 403 ,被应用服务器权限拦截了返回 http status 200 加业务状态码是很合理的
yidinghe
2022-12-03 21:38:18 +08:00
首先,协议层的错误和应用层的错误区分开来是对的。其次,强行要求业务逻辑绑定 HTTP 状态码,而且这个状态码可能会沿着链路传播给非 HTTP 协议的调用,这难道不是坏习惯吗?
SenLief
2022-12-03 21:40:28 +08:00
我觉得还是区分资源和业务,业务这块返回 200 也正常,毕竟 http 状态码不能完全知道错误在哪,但是请求确实是成功的。所以只要请求成功返回 200 就可以吧
okakuyang
2022-12-03 21:42:48 +08:00
这类问题隔一段时间就会有人问。
对于前端来说,网络连接问题是最优先的,其次才是后端返回的各种数据异常问题,反正异常处理就这样分层了。

请求成功返回 200 ,前端就知道网络请求成功了,然后再去判断这个请求是否业务上成功。
异常提示字符串直接从后端返回 json 里取,这样大大减轻了前端的工作量。
后端只返回几种意义不明显的状态码,前端还要了对照这些状态做不同的显示,没点效率。
edis0n0
2022-12-03 21:45:29 +08:00
@okakuyang #12 后端返回 200 ,前端就直接把返回当作获得的数据,后端返回 40x ,前端就知道遇到错误了,如果返回是 json 就按照 error 来 parse ,否则按照 http 状态码弹出缺省错误信息不是更好吗?
edis0n0
2022-12-03 21:46:08 +08:00
@edis0n0 #13 这样就少了一层无用的包装,还充分利用了 http 状态码
dddd1919
2022-12-03 21:51:52 +08:00
把错误码放在返回结果里,不管是 http 还是内部 rpc 或者其他协议,通用性都更强

另外 http 的非 200 返回在很多框架里定义为异常,各种请求端还要加 try catch ,服务端除了处理业务异常还要考虑 http code ,用的也麻烦
Iamsonny
2022-12-03 21:52:19 +08:00
没啥问题,公司内部统一规则就行。
edis0n0
2022-12-03 21:54:27 +08:00
@dddd1919 #15 http 的非 200 返回在很多框架里定义为异常 能不能举一个流行框架的例子,我好像还没见到过这种
jhdxr
2022-12-03 21:57:33 +08:00
前阿里移动端路过,你根本无法想象当年(之所以说是当年是因为我离开多年不知道现在如何,并不代表现在好转了)各大运营商等中间网关有多疯狂。
上面说 4xx 篡改内容都算小的,最严重的一次是某地小运营商(可能是为了省网间结算流量)把所有请求都简单粗暴按照 url 缓存了(哪怕是 post 请求),直接导致了当地用户大量串号。

另外小小偏题一句,你标题里已经论断了这是『坏习惯』,那别人出来反驳一下也正常。
swulling
2022-12-03 22:10:14 +08:00
@jhdxr yes ,当年百度全站 https 的一个主要收益就是因为反劫持从而提升了数个百分点的收入。

劫持会直接替换掉百度广告,丢掉很多点击收入。
dddd1919
2022-12-03 22:20:17 +08:00
@edis0n0 补充下这里指后端框架,java 的很多都是

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

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

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

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

© 2021 V2EX