为什么要区分不同的 http 状态码?想说服同事

2022-04-13 10:28:42 +08:00
 dunhanson

我的个人的理解还是,这么做比较规范

但是同事的理解更多是优点好处是什么

比如用户登录错误之前的方式都是返回 http 状态码 200

{
  "code":4001001001,
  "message":"用户登录失败"
}

现在按照规范应该是,返回 http 状态码 401 ,然后 json 还是老样子

17790 次点击
所在节点    程序员
176 条回复
Vitta
2022-04-13 22:20:56 +08:00
一把梭的你们是不是很多都是 java 开发
yaott2020
2022-04-13 22:28:51 +08:00
我自己写代码的话,除了常用的错误就会用,比如 401 500 503 403 404 。如果是应用层级的错误一律 200 OK ,然后再在返回包里面标注错误码,错误信息。
bobo2
2022-04-13 22:50:22 +08:00
@Chad0000 正常来说,不都是 err.log 存放错误日志,out.log 存放接口输出日志么,都返回 200 ,不就都存 out.log 了,日志层再怎么实现也是要判断输出日志和错误日志的吧
neutrino
2022-04-13 22:50:59 +08:00
@Vitta 语言无关,一把梭业务逻辑更清晰,前后端更舒服,何乐不为。
binux
2022-04-13 22:51:18 +08:00
@lmmlwen 那么多公司规范都给出来了,还有没有人用,你真是坐井观天。
adoal
2022-04-13 22:56:03 +08:00
如果发生错误,是与业务逻辑无关的系统错误(不论是客户端还是服务器,自己方还是外方),还是与系统无关的业务错误?前者表明系统没毛病,是用户操作的错,要由用户解决,并且允许出现的常态;后者表明用户操作没毛病,是系统的错,由技术人员(某方的开发或运维)来解决,即使发生的频率不低也不应该视为允许出现的常态。有些错误很容易分辨出属于哪一类,而有些就需要技术和业务都精通的老司机才能准确分辨。HTTP 状态码和 body 数据之争的本质是,针对这两类错误如何设计报错机制。
aragakiyuii
2022-04-13 22:57:36 +08:00
infra 都没有的就随便一把梭了,毕竟能用就行
txydhr
2022-04-13 23:10:24 +08:00
能 200 梭哈
意味着也可以 404 梭哈
反正都能打开网页
MrKrabs
2022-04-13 23:42:07 +08:00
http 状态码才几个啊,restful 也就是个野鸡标准罢了,又不是圣旨
a132811
2022-04-13 23:43:13 +08:00
就算是完全用 200 一把唆, 也得判断 http code 。

如果返回结果确实需要自定义 code ,就需要两层处理:

// 第一层 无论如何都是要处理的
if(res.statusCode==200) {
// 第二层再判断一下 code
if(res.json().code==0){
// 正常业务代码
)else if(res.json().code==1){
raise Error(res.json().err)
}
}else if(res.statusCode==400){
raise Error(res.body)
}else if(res.statusCode==401){
// 未登录.....
}else if(res.statusCode==404){
// .....
}....500 ,501 xx
--------------------------------------------------------------------------------
如果返回结果简单,就用一层就够了。
(很多公司的 api 其实就一层: https://v2ex.com/t/846785

// 只有第一层
if(res.statusCode==200) {
// 只要是 200 , 就是正确的结果,不需要加第二层 code 判断
// 正常业务代码
}else if(res.statusCode==400){
raise Error(res.body)
}else if(res.statusCode==401){
// 未登录.....
}else if(res.statusCode==404){
// .....
}....500 ,501 xx
------------------
jinliming2
2022-04-14 00:23:46 +08:00
HTTP 2xx: 正常结果,一定是成功的操作,仅包含业务数据,不包含其他内容 status: success 之类的
HTTP 4xx: 客户相关错误,状态码可以提供大范围的错误信息分类(未登录、无权限、访问频繁之类的),这些错误都是正常情况下的错误,可以给出具体理由的,属于预期错误,通常理论上完全不需要开发、运维介入的错误,用户自己知道错哪了,能不能解决也是用户自己可以判断的。
HTTP 5xx: 服务相关错误,可以通过状态码进行分类分为业务错误和网关错误。如果是业务自己的错误(比如数据库连接断了、空指针了之类的),那就是 500 ,这类错误通常是需要开发人员去定位的异常情况,也就是未知的 bug 。而网关错误通常是明确的,配置错误 502 、临时维护 503 、业务挂了 504 。
其中 4xx 和 5xx 错误,状态码只提供大分类,响应结构中再包含可公开的具体的细分错误详情。

举个例子:用户访问了一个不存在的 URL ,分为 3 种可能,1 业务错误:没有这个资源,2 业务错误:没有权限,同时需要防止用户了解资源的存在性,3 网关错误:找不到对应的业务。
对于 1 和 2 来说,返回 HTTP 404 再合适不过,HTTP body 指示找不到可访问的资源;而对于 3 来说,应该返回 502 ,HTTP body 指示找不到可用服务。

这样,在网关记日志的时候就不需要解析 HTTP body 了,通过状态码就能过滤出错误日志,并且按照大分类分好:
通常开发只需要关注 500 的业务错误、运维关注除了 500 以外的其他 5xx 错误。而 4xx 的错误通常只需要关注计数就行,错误数在一定量级以下就是正常,超过一定量级就需要报警让开发介入调查了。2xx 的日志只在查业务逻辑的时候才会关注,平时直接忽略。
seakingii
2022-04-14 00:25:48 +08:00
@afewok 不用盲猜,上面已经有人说了.
Chad0000
2022-04-14 03:39:18 +08:00
@bobo2
这都什么年代了日志任然需要依赖纯文件?结构化日志中间件了解一下: https://datalust.co/seq
mmmfj
2022-04-14 06:47:48 +08:00
有时候前端是允许一些异常情况的,但是你返回个 http 异常,太难区分了,不知道是真的服务器炸了还是特殊情况
summerLast
2022-04-14 09:30:53 +08:00
自己定义格式有什么好处吗?
nkidgm
2022-04-14 09:32:13 +08:00
以前还会争论一下,现在这两个其实都有存在的理由,对于公司项目跟着团队 leader 走就行了,对于自己的项目用哪个看自己习惯。
nyakoy
2022-04-14 09:36:47 +08:00
以前是 200+post 一把梭,现在在往 restful 走。毕竟有规范还是用规范吧
yc8332
2022-04-14 09:40:10 +08:00
感觉搞偏了。反正我们都是 code 是在返回数据里面。。http code 是代表请求的状态吧?我们从来不去改这个东西。
newmlp
2022-04-14 10:08:33 +08:00
当然 200 一把梭,业务层的错误为啥要用传输层的错误码表示?
sunny1688
2022-04-14 10:09:24 +08:00
我这边的做法是,200 状态码,业务数据一定有,而且前端那边不需要做任何判断,拿到数据直接处理即可,就拿 ajax 来说,非 2xx 状态码,走的是 error 回调,很多开源请求库也都是按照这种方式去处理,所以我这边是只用了 200+4xx ,5xx 就不用说了,一般也不会手动抛出 5xx 状态码吧!

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

https://yangjunhui.monster/t/846679

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

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

© 2021 V2EX