我讨厌http状态码一律200

Categories:

昨晚在知乎偶然刷到个月经贴(月月有人问,年年有人愁)

为什么那么多公司做前后端分离项目后端响应的 HTTP 状态一律 200?

赞同一律200的一些观点虽然我不认同,但是有些也有道理。

这里我就一一贴出来了。我这里只写我自己的观点。

我是旗帜鲜明地反对一律200的。

对一些观点的反驳

很多人说别把HTTP状态和业务状态混为一谈。但问题是很多人区分了那么多业务状态却也没对应的业务逻辑呀,区分完状态后一律alert msg?这个垃圾桶分类后全用一部垃圾车拉走有什么区别?

有其他人回答提到监控,一般非200可能都会被纳入监控告警,是不是验证码填错了也来个告警? 我想说,监控不是发生一次就告警,一般是单位时间范围内次数达到限制才会告警。 如果验证码大量报错,要么有人恶意攻击,要么验证码挂了,要么验证码太难以识别可能真的需要调整验证码生成难度,等等等等,这些本来就是该分析的呀。

正常(200)才是占大多数的,如果你的错误出现次数(非200)快赶上正常情况,要么是项目质量太差,还没达到上线条件就不该上线,要么就是你没合理定义 什么是正常,什么是错误。

至于还有人提到200确保链路通讯正常出错肯定是业务逻辑,非200就是网络网关nginx等非业务错误。我想请问,你家天天发版,你家天天网关nginx出现宕机?就算真的出现了,看看通过body里的内容即可判断出是业务还是基础设施故障。如果看不出来(比如吃掉异常就返回4个字系统错误!,这些就是单纯没合理抛出业务异常。

至于前端少传参数,开发联调阶段发现不了,你搞什么开发?

至于用户填写信息错误,现在为了体验都是提交表单前就把能做的检验都做完,理论上很少出现。如果大量出现信息填写错误导致的检验不通过,那为了用户体验是不是该考虑把检验前置,甚至优化业务流程呢?

在我看来,即使是业务上的状态,正确情况 也应该永远只有一种

应该合理划分业务上正常和异常的边界

例子1,资源找不到。

  1. 如果资源找不到是不应该的,不存在对应的资源时肯定是某些东西出错了(比如自己随便伪造了个文件id,或作者删掉了),那就该404。

    这时的正确情况只有一种,就是返回1个资源。

  2. 如果业务上存在或不存在资源都是合理的,那就该把返回定义为数组,找不到就返回[],这时是应该返回200的,因为业务上是允许的,是正确的。比如文章的评论可以是0个,可以是多个。

    这时的正确情况也只有一种,返回1个数组。这时资源找不到就用[]来表示。当然也可以返回null或{}空对象等来表示资源不存在,反正尽量挑一个服务器段、客户端都方便的。

    如果资源不存在是合理的,你还要返回404,导致大堆的404监控,这明显就是你不合理定义正常和错误的典型案例。

例子2,订单创建失败。

正确情况永远只有一种,就是下单成功。

其他的不管是缺货,购买数量达到上限,价格失效,等等全部应该是非200的。

有些人说这里可能有逻辑,不同的错误不同的处理,比如缺货跳去订阅商品到货通知,购买上限就推荐其他商品,价格失效提示刷新。

我个人始终倾向正常情况只有一个,只要没有下单成功都不是200。200直接返回结构体,非200再区分这些不同场景。

{
  "reason": "price_expire",//英文单词不必 code:10001 香?
  "detail": "商家已修改商品价格"
}

如果你觉得本文对你有帮助或不错,可略表心意,请我喝一杯冰可乐。

Comments