

为什么要区分不同的 http 状态码?想说服同事
source link: https://www.v2ex.com/t/846679
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

我的个人的理解还是,这么做比较规范
但是同事的理解更多是优点好处是什么
比如用户登录错误之前的方式都是返回 http 状态码 200
{
"code":4001001001,
"message":"用户登录失败"
}
现在按照规范应该是,返回 http 状态码 401 ,然后 json 还是老样子
wolfie 4 小时 40 分钟前 38
ZE3kr 4 小时 38 分钟前 via iPhone
gam2046 4 小时 33 分钟前
REST 那一套说是可以更有语义化,但由于实际业务的复杂性,依靠 HTTP CODE 很难表达出含义,最终还需要在响应体内自定义错误码,这就是重复工作了。
统一返回 200 以及统一 POST 一把梭,确实不够优雅,但是能用,而且也没什么副作用。
yuxing1171 4 小时 33 分钟前 18
monkeyWie 4 小时 31 分钟前
yuxing1171 4 小时 30 分钟前 1
cpstar 4 小时 29 分钟前
一个写在 ajax.ok()里,然后 if errcode ,这就区分了协议基础问题和业务运行问题
JamesMackerel 4 小时 27 分钟前 via iPhone
angryfish 4 小时 25 分钟前
作为使用 spring boot 的,我觉得返回 401 ,后端的工作量是增加了的。不知道前端是否会增加。
Jooooooooo 4 小时 22 分钟前
异常状态随便举例子 下游调用超时, 内部异常(比如空指针), 下游异常数据, 用户没登录, 用户状态不正确, 用户行为不正确, 可能是爬虫(返回打乱的数据), 可能是爬虫(不返回数据)
我们是用自定义 code:0 表示正常, 其他值表明是各类异常.
AyaseEri 4 小时 15 分钟前
我的意见就是,如果这个规范可能导致你们加班时长变多,那就不要实施。
alswl 4 小时 9 分钟前
如果上面三者做不到,干嘛不遵循标准的 HTTP Schema 协议?
BeautifulSoap 4 小时 5 分钟前 3
200 一把梭也是有它自己的好处,最典型的就是调用对方 api 的时候,只要不是 200 那你就知道这次 api 调用 100%是出了幺蛾子了,而且错误不在对方服务器上面
而区分不同状态码的话,你是没法单纯通过状态码来判断这个 api 请求到底是 API 本身出错了,还是对方服务器前面的 Gateway 或者 Load Balancer 因为什么原因出错了返回了非预期的 http 状态码。从写代码角度,反正到头来我还是得取出返回值具体分析到底是服务出错了还是其他的网络错误,比 200 一把梭麻烦多了
kaedeair 4 小时 5 分钟前
机器 A 使用 token 认证,当不同用户在机器 A 登陆时,401 就会有问题,会分不清是机器的 token 过期还是用户名密码错误
我这边都是用 json 的 code 表示对数据的处理结果,外层的 httpcode 表示数据的传输情况
twing37 4 小时 4 分钟前
制定标准的意义就是为了更清晰不是么.
如果 x 公司的标准非外部,爱咋弄咋弄~ 黑话也是话.
但如果跨出门了.有个更标准的规则遵循.即说普通伐更省事
1000copy 3 小时 58 分钟前
你如果以自己为中心,就把电信局当成一通道,至于电话局定义的 200 ,400 这些代码,你管他呢,你只管摘机+说话+关机。至于摘机代码是啥,你管他的。你把我要传递的传递过程,如何解释,是我的事情。
你以电话局为中心,那么你就真的要考虑如何诊断,如何监控,各种屁事。
所以你是写 HTTP 插件的,还是你写软件,而 HTTP 只是你的传输通道?
学到了 HTTP 各种协议,就忘掉了软件需要封装,分层了吗。
为什么软件内需要知道通道的细节呢。知道了细节,软件就会被拴在通道上了。
今天 HTTP 定义了 200 ,300 ,400 ,500 ,明天换成别的协议,是 OK ,Failure ,你的软件就改了底朝上了啊。
guyeu 3 小时 56 分钟前
chendy 3 小时 55 分钟前
市面上的开发,知道 http status 是啥的其实都不多
直接无视这个概念,全部塞进 body 里返回可以避免很多不必要的沟通和解释
另外如果需要做分析统计之类的,错误代码往 header 里塞一份就行了
另外不是国外没人用全 200 ,只是常见的大公司接口做了状态码区分,小厂的,传统软件厂的接口也有全 200 的
adoal 3 小时 48 分钟前 9
HTTP 状态码数量就那么一些,而业务的结果状态数量是不可控的,随着业务接口膨胀起来,如何映射到 HTTP 状态码的分类,如何表示业务状态细节,都不是空口说一句优雅、规范就能解决的,是要实打实一个个干出来的,要踩坑踩水甚至踩屎的。
在实际架构中,可能经过 API 网关以及其它各种反代和中间件,业务状态逐级向上传递,业务状态码跟基础设施状态码在同一个命名空间,必然会导致设计工作量和难度更大。
最后,在 HTTP 状态码的命名空间里表示业务状态,受惠最大的其实是做系统运行状态监控的。但,同样的问题,如果没有业务和技术都足够资深的老司机来做设计,很可能出现监控信息的无序,失去意义,甚至搞出用 AI 过滤有效监控异常的笑话。
先不说团队素质、集成方团队素质、遗留系统对接之类的非技术问题吧。
总之,理想很美好,但是,陈皓给用户方做咨询的顾问团队能做好的事,不等于人人都能做好。
MrSheng 3 小时 36 分钟前 2
来贴段代码让大家看看
talk is cheap,show me the code
daimubai 3 小时 23 分钟前 14
全 200 也不合适吧,通用的状态码应该保留
200 统一表示成功。
400 统一表示客户端参数错误、业务错误
401 没登录
403 没权限
404 接口不存在(一般 web 框架会处理。 如果请求的资源不存在不返回 404 的,比如用户不存在,就返回 400)
500 统一表示服务器异常
对于 200 ,响应体要不要包一层,可以再开一个贴子开撕,我的话是包的:{code:"0", message:"success",data:{}}
如果 400 或者 500 的话,返回{code: "-1" , message: ""},-1 表示通用的业务异常,前端只需要取 message 弹窗即可。如果前端需要对业务异常进行逻辑判断,然后再自定义 code ,前端根据 code 去判断。
如果你的项目要做 saas ,给其他公司接,你也全 200 ?
Freeego 3 小时 10 分钟前
adoal 2 小时 56 分钟前
yangyaofei 2 小时 52 分钟前
矛盾不矛盾
ClericPy 2 小时 44 分钟前
不论对错, 只论适合不适合, 有些挣快钱的公司真的就是能用就行. 而且多数情况不怕做错, 怕的是不统一, 一错到底比有对有错带来的危害要小一点
你要做的大概不是来 V2EX 找认同, 而是提升自己然后尽早摆脱这种环境
yangyaofei 2 小时 43 分钟前
反正. "能用就行" 这种我是不敢用的, 必然会在能写屎山的地方写屎山, 简单的复合协议都不愿意做, 我不认为会写出好维护的代码.
手艺人都有手艺人自己的优雅和细致, 手艺人和大锤 50, 不一样.
Biwood 2 小时 40 分钟前 2
最开始是运营商或搜索引擎根据 404 劫持页面,然后是网站服务方不得不全站 200 ,在然后形成了习惯、偷懒,美其名曰灵活、自定义规则,明明有 https 了却还是 200 一把梭。封闭文化始终存在与这个国家的方方面面,这根现在简体中文互联网整体的割裂基调是一致的。
V2EX 虽然有不少程序员,但是这个问题如果放到真正的技术网站,甚至根本都不应该成为一个问题。
adoal 2 小时 40 分钟前 11
如果是为了监控基础设施,我 JSON 里封的是业务逻辑层面的错误,关你基础设施屁事?
如果是为了监控业务错误,却嫌错误代码封在 JSON 里不方便……你就是想让我把业务错误代码放到 HTTP 里去对吧?你是不是觉得我这边各种各样的业务错误怎么映射到 HTTP 那几个状态码里很简单?你个普罗米修斯崽懂个屁的业务。
我的业务 API 又不只是为了让你来做监控而存在的,我要给别的业务单位调用啊。HTTP 状态码没出错,业务状态码出错的时候,可以去找管业务系统的人处理,HTTP 状态码出错了找管基础设施的人处理,这两拨人不是同样技能的啊。业务端有个什么狗屁错(而且还不是那种 unrecoverable 的外部环境错,是业务逻辑的错,要业务用户处理的)都返回成 HTTP 错误码一级一级传上去,查个业务级错误都要基础设施的人联动,这是制造民怨吗?你来给我做基础设施架构让我有办法一键定位出错的层次和节点吗?可是我只能拿到够做业务功能的经费,而且是单个单个项目做,没有做基础设施的条件,我让一个行业人士起家的地方性行业性中小型业务信息化开发商给我做业务系统开发的时候顺便免费做一套云原生的微服务的可观测的可这个那个狗屁的基础设施,并且以后的其它同类业务开发商要逼着他们不允许用自己的积累,一定要做在这些所谓现代的平台上,这忒外祖母的现实吗?
libook 2 小时 36 分钟前 2
HTTP 是有标准规范的,所有状态码都有定义。https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
需要注意的是:
1. 标准里对状态码的定义仅与 HTTP 协议通信的状态有关,跟业务无关,比如 401 仅代表 HTTP 协议层未认证,不代表业务上未认证,虽然有时候两者是同一件事。
2. 通用的 HTTP 客户端和服务器软件及其相关的框架和库都是会默认遵照 HTTP 标准规范来设计的,你可以不按标准使用,但你使用的软件、框架和库可能依然会按照标准来反应。
3. 有的 API 设计风格(如 REST )会把业务状态和 HTTP 状态绑定一起,但这是建立在业务状态足够简单的基础上的,HTTP 状态码就那么多,无法把所有业务状态全映射到,比如登录失败可能有多种原因,客户端需要对不同原因进行判断再做反应,此时仅一个 400 状态码是没法解释清楚的。
建议先对 API 进行梳理,然后划分出哪些接口要用什么设计风格;对于可以遵照 HTTP 标准来设计的接口,需要去分别考虑每种返回情况的 HTTP 状态是什么、业务状态是什么,给出正确的 HTTP 状态,并在载荷中写明业务状态。
adoal 2 小时 36 分钟前
binux 2 小时 32 分钟前 via Android 4
你知道国内 200 一把抓的风气恶心之处在哪吗?
不在于这么做理由,或者说觉得不区分有多好,而是他们根本就不去想理由,麻烦就不去做,别人发布了规范也不去看,闭门造车而洋洋得意。
我很同意 coolshell 里的一个观点,rest API 规范不一定普世,但是人家好歹有成文的规范,也会写这样选择的原因,你可以自由讨论,指出它的问题。你觉得 200 一把抓好,那你见过有那个大厂有成文的规范 guidance 吗?
整天在那讨论政治,说没有参与权,到了真正程序员能有话语权的标准的时候又在那里摆烂,简直就是叶公好龙。
Biwood 2 小时 23 分钟前
CEBBCAT 2 小时 4 分钟前
coala 2 小时 3 分钟前
http code 500 服务器真的内部错误.
http code 401 未授权
http code 200 (业务 code 400 是密码错误这种), 就是业务上的错误,我认为是成功的, 让让前端会有个统一的拦截器去处理业务 code
原则就是 http code 必须保证符合原有的意思, 200 里面再加上业务 code,
但是像是未授权这种, 可能既是业务错误, 也可以理解为 http code 错误 就很头疼
RESTFull 我遇到的问题(Java):
1. 有些内网的防火墙不允许 delete 这种请求进去.. 很让人无语
2. RESTFull 一个 URL 可能对应多个接口, 按照路径配置各种规则的时候 , 日志打印, 就打地址的话看不出调用是那个具体接口, 解决其实也能解决, 日志加上请求的方式, 规则按请求方式 + URL 去配置.
3. 就是理解不明确的, 不知道定义为那种方式的接口
4. Get 传大量查询参数, 不方便的接口, 前端意见很大, 后端接收也不是很方便, 偷懒用 Post 了不少
我觉得 Get 传参限制太多了, 通常只能携带路径参数 (其实理论上服务器也能接收 Get 请求体), 要是能加一种查询的
类似 Get + 能发请求体就好了, 其他的问题都是可以解决,最多麻烦点, 慢慢都会好
seakingii 1 小时 50 分钟前 1
API 接口还不一定用 HTTP 协议传输呢.
纯粹是技术和商业的问题,上面那些从不用 HTTP 状态码,上升到国家,文化,简直搞笑.
a62527776a 1 小时 38 分钟前
事实上你需要登陆后才能读取数据的接口 不需要登陆也能访问,能理解区别吗?意思是 401 并不是业务层的 code
曾经有个领导 非过来搞这套 烦都烦死了
3dwelcome 1 小时 34 分钟前 1
原因是只要遇到 400/500 这种 HTTP 错误状态码,我就马上能知道是 CDN 或者网关之类出问题了,不是我的业务逻辑部分出问题了。
你们可以查一下 RFC7231 设置 200 的初衷( The 200 status code indicates that the request has succeeded ),仅仅代表本次网络请求成功,没有任何别的附加实际业务的含义。所有业务相关的内容,请在 payload 里自己处理。
raptor 1 小时 32 分钟前
但是发展到一定程度就会有问题,比如需要上 API 网关,在其中处理一些如监控,日志,告警,流控之类的时候,本来用 HTTP 动词和状态码可以简单处理的事情,变成需要解析 BODY 的时候,你就准备去填自己挖的坑吧。
当然,如果在可预见的未来,你也不会达到这样的程度,那就随便了——大概率是这样的。
seakingii 1 小时 21 分钟前 1
put ,patch,delete
楼主你想不想用?
用了,有时网络链条中,某些环节对这些动词兼容的不好,
不用,你怎么不遵守规范呢?
yolee599 1 小时 13 分钟前
Chad0000 52 分钟前 via iPhone
很是赞同。业务是业务,http 服务是 http 服务。业务监控自有各种监控中间件。否则哪天不用 http 了或者需要兼容另外一种协议,就完犊子了。
Kinnice 52 分钟前
监控:
1. 业务监控,那解析 body 是应该的,
2. 链路监控,业务出问题和你链路有啥关系?
3. 混合监控,就算你看到了 4xx/5xx 你不解析 body ,能准确反应出原因? httpcode 可没这么全
nginx 重试:
业务出问题了,你网关重试个啥? 比如我 post 添加一条数据,失败了,你 nginx 还帮我重试一下?
iyaozhen 52 分钟前
pengtdyd 51 分钟前
20X 、40X 、50X 这些是 HTTP 状态码和业务状态码混淆在一起怎么做监控???
错误码设计可以参考阿里巴巴《 Java 开发手册》错误码的制定原则:快速溯源、简单易记、沟通标准化。
1 )错误码必须能够快速知晓错误来源,可快速判断是谁的问题。
2 )错误码易于记忆和比对(代码中容易 equals )。
3 )错误码能够脱离文档和系统平台达到线下轻量化地自由沟通的目的。
iyaozhen 47 分钟前
我说的是网关层面的搂底监控。这种时候各个业务 json 都不一样,解析不了,而且影响性能。有个 5xx 监控会好很多
nginx 重试
说的是幂等的重试,比如 GET 、PUT ,当然如果 POST 一把梭就做不了了。
jjwjiang 43 分钟前
拿 400 和 422 举例,422 可以很容易的覆盖一部分业务错误,所有参数上的不合法都可以归到 422 里,对监控更容易,跟别的合作伙伴做对接也更简单。
比如 request 定义是
{ n:int, s: string}
而 n 要求大于 0 ,s 要求不能为'',那么
{'1'}
就会对应到 400
{n:'1',s:1}
{n:-1,s:''}
对应到 422
而 n:1998 会造成业务上出错,那自然是以 200+message 返回
界限很清楚也很好用,422 我就去检查参数值,400 就检查参数格式,而 4 开头的都会被浏览器认定为 client 错误,事实上也确实是作为 client 的调用方有错误,不挺好吗?
rest 规范你觉得不合理就选择使用就完了,全盘否定或者全盘肯定都是不现实的。
adoal 40 分钟前
Actrace 34 分钟前
HTTP 协议的状态码都已经是最顶层了,不权威的。
...说笑的。
既然 https://coolshell.cn/articles/22173.html 里说到 HTTP 是协议的一种,STATUS 属于协议的部分,而承载的 BODY 才是业务内容。那么我认为用于处理业务问题的业务协议及其内容,与 HTTP 协议是两种不一样的东西,HTTP 协议的所有内容应该专注于它本身需要专注的部分。
比如 STATUS 503 是服务不可用,服务不可用是服务器硬件资源的问题,而不是业务不可用。尽管业务和服务器状态本身是互相关联的,但是我们应该尽可能去解耦,让运维团队专注解决硬件资源问题,业务团队专注解决业务问题。
虽然大多数情况下,你一个人就是一支军队,所以所有问题都自己解决的话,倒不是有必要区分得那么明显了。
所以还是看业务规模吧,以上个人观点仅供参考。
3dwelcome 33 分钟前
1. 监控怎么做?都是 200 ,怎么知道错了”
监控可以另外写 API 。我们的业务不仅仅是 HTTP 协议哦。HTTP 协议只是业务传输载体之一,还有 TCP 封装和 websocket 封装,底层调用的业务逻辑代码,是同一个模块。
james2013 32 分钟前
客户端哪里知道后台接口使用 4xx,5xx 呢?比如后台在某些 4xx,5xx 里是框架自带的错误码,而不是固定的 json 对象
还不如直接返回 200,在统一的返回对象里统一处理和提示
jjwjiang 27 分钟前
lolizeppelin 21 分钟前
正确设计是所有错误以 raise
http 返回的部分加一个 translation 把内部 Error 翻译成 Http Error
最好 rpc 也能把 raise 的异常传递
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK