RESTful API 中的 Status code 是否要遵守规范

2019-02-22 09:58:06 +08:00
 Muninn

缘起

事情是这样的,我在知乎受到邀请回答一个问题,主要是问 ID 找不到到底要不要用 Status 404。我回答的还是比较早的,那时候只有一两个回答。我本来以为这是没啥争议的,在一个学术的地方讨论学术问题,当然是要遵守规范了,结果过了几个小时大跌眼镜。自造 code 党竟然支持率第一,还好平时见的也很多的全 200 党没有受到支持,不然真的吐血了。

为什么要遵守规范

一般那种说特殊情况特殊处理,不要拘泥于规范的人,大多都是自己没搞清楚某些知识,拿这句话当作偷懒的借口。其实一般做项目没那么多特殊情况。

为了更好的适应各种库

大部分完善的 HTTP 请求库,都会依照 RFC 的规范去设计错误处理的流程,虽然处理方式各有不同,但一定会在文档说明错误处理的部分的。使用 RFC 标准能最大限度的兼容各种 HTTP 客户端。你说现在你用的 HTTP 客户端不处理 Status Code,但是你没法保证将来不重构,重构的时候还是不处理。

一般调用 api 使用 js 或者 python 的概率比较大,我们看看知名的库。在 js 里,最近比较流行的 axios 默认会把 200 系列外的 code 归到异常里。在 python 里,最流行的 http client 是 requests,它更为详尽的预处理了 status code。

为了开发者更好上手

另外在管理团队的方面,我们的原则是尽量的减少一个项目的“规范”,这样才能更容易去遵守。能用标准的地方,一定不要自己定一个更复杂的规则。无论是服务端的维护者还是 API 的消费者是会换人流动的,每个进入项目的人熟悉一大堆无谓的自定义项目规范都要成本。

更简单的办法是参考大厂

其实给项目定规范,最不靠谱的是自己拍脑袋,稍好一点的是去知乎或论坛问,更好一点的是去 google 搜,最简单的是直接去看大厂的产品或者规范啊。API 本来就是个公开暴露的东西,还有比这更好找参考的吗?我们来看看:

我的建议

很多人也许用着很简陋的 Web 框架,导致误以为返回了错误码,就不能返回 Response Body 了。其实你返回 204 外的任何 Status Code,最好都伴随着返回 Body。

在项目规范里,可以规定 Status Code 遵照 RFC 标准,或者选定一个集合出来,把一些不常用的去掉。然后如果不是 200 系列的代码,必须伴随着这样的一个错误结构:

{
    "error": "UserNotFound",
    "message": "该用户没有找到"
 }

这样错误分为了三层结构,第一层是 Status Code,使用者能大概知道是什么问题。第二层 Error 是一个 Key 使用约定好的无空格的英文,给使用者做判断用,使用者可以根据 Key 自定义接下来的操作。第三层是 message,有些 Key 使用者可以决定直接把 Message 显示个终端客户。

如果是微服务项目,需要要求每个服务不管用什么语言,都要把错误统一成这个样子。如果开发者告诉你框架不支持,那这一定不是个好框架,改重构了。好的框架不仅能让你自定义错误内容,还能做到所谓的“框架自己出错的返回”也由你自定义。比如路由没有找到之类的。

最后

我实在不明白为什么一个最扯淡的答案,要自造一个 600 的 status code,可以得票第一。知乎用户到底有没有一点独立的判断精神啊,只要装的一本正经,再摆出来一点资历,哪怕是胡说八道,大家也纷纷点赞。也许真的不适合在知乎去回答技术问题了。

7037 次点击
所在节点    编程
38 条回复
WilliamYang
2019-02-22 10:36:06 +08:00
支持你遵守规范, 为你点赞
casillasyi
2019-02-22 10:38:24 +08:00
不遵守规范,就是给后人埋坑
huangdayu
2019-02-22 10:53:57 +08:00
我是用 status code,然后内部也定义了 msg 对应的 code
momocraft
2019-02-22 10:56:00 +08:00
故意不遵守的不必硬要叫 rest
relaxgo
2019-02-22 11:10:29 +08:00
计算机行业最可怕的人,就是这种不遵守规范,自行其是的人了。居然还自行定义个 600,如果之后规范里增加了 600,岂不是冲突了
feiyuanqiu
2019-02-22 11:12:56 +08:00
restful 这东西没什么技术含量,谁都可以抒发一下个人见解,导致争论不休。到最后就变成个人品味的争执了,谁都说服不了谁。有时间有闲心的话可以去吵一吵,我先亮一下我的屁股,我是 paypal 规范的忠实支持者:

https://github.com/paypal/api-standards/blob/master/api-style-guide.md#http-status-codes
relaxgo
2019-02-22 11:20:52 +08:00
这种不遵守规范,还污染规范的,更是让人气愤
pubby
2019-02-22 11:26:44 +08:00
个人比较讨厌 restful
全部 post,全部 200
mcfog
2019-02-22 11:55:38 +08:00
首先 restful 根本不是规范,而是设计风格
其次,你参考的大厂 API 是第三方整合用的 API,而很多人讨论的背景是自己公司做给自己人的场景
restful 是学术(或者说学院派)没错,但你怎么就觉得知乎是学术的?这个问题是学术的?我怎么看怎么觉得这个问题是工程角度的

工程问题并不是学术问题,不是是非黑白问题,而是权衡和折中的问题,我真的从没见过哪家的设计是 100%按照全套 restful / rfc 的东西来实现的,patch 方法 + `application/json-patch+json` 的修改接口看都没看到过,HATEOAS 的东西最多在分页里见过一点
Muninn
2019-02-22 12:06:51 +08:00
@mcfog RESTful 是基于 HTTP 通讯协议的一种数据交互风格,

我们讨论的是要不要遵守 `HTTP 协议规范` ,不是 RESTful 的规范。你连这个省略都看不懂,后边还说了这么多……
Muninn
2019-02-22 12:08:40 +08:00
@WilliamYang
@casillasyi
@huangdayu
@relaxgo

感谢各位的支持,看来 V2 还是倾向于尽量遵守规范的比较多。
mcfog
2019-02-22 12:43:20 +08:00
@Muninn HTTP 协议更不是规范了,你说用 600 状态码违反 HTTP 协议那是对的,用 200+body 内容表示业务状态完全符合 HTTP 协议,不符合 restful 风格而已

你觉得我不懂的话那就这样吧,祝你工作顺利
MeteorCat
2019-02-22 12:45:27 +08:00
返回 200 状态,body 里面加个 status 就行了,HTTP 状态真的没必要搞什么幺蛾子
HelloAmadeus
2019-02-22 12:47:33 +08:00
Failures MUST be reported in the 4xx or 5xx range. This is true for both system errors and application errors.同意这个观点
micean
2019-02-22 12:50:01 +08:00
看机房环境
有的甲方机房管理的莫名其妙,防火墙瞎 JB 配
icylogic
2019-02-22 13:28:48 +08:00
我网站关了以后就给人返回 418 ……
justfindu
2019-02-22 13:55:03 +08:00
应该是支持 http status code 吧. 毕竟程序内其他非 2xx 都是抛异常, 然后统一处理. 方便中断. 一般异常再加上自有 error code.
hilbertz
2019-02-22 14:00:50 +08:00
restful 设计局限性太大,正常程序员思路都是用 rpc
tongz
2019-02-22 14:05:16 +08:00
@icylogic #16 我网站关了以后直接在 nginx 里返回 http code 666, 哈哈.
passerbytiny
2019-02-22 14:11:44 +08:00
除了“ ID 找不到用不用 404 ”,其它的都认同。“使用 ID 未找到资源”并不能完全等同于“资源不存在”。如果严格考虑上下文的话,直接用一个 ID 形式的 URL 去获取资源但是没找到(场景一)是“资源不存在”,根据前置检索的结果拼接一个 ID 形式 URL 去获取资源但是没找到(场景二)是“未知原因引起资源已不可用”,场景一是 404,场景二应该是 500,场景一如果考虑资源被禁用、资源被删除的情况,是不是 404 也不好说。
“使用 ID 未找到资源”这个应该还是要根据不同情况不同分析,面向公众的开放接口应当返回 404 + error body,面向信息管理系统前端界面的后端接口返回 500 + error body 就更合适,而如果是纯 HTML 资源获取的话,返回 200 + 提示界面才是更好的选择。

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

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

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

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

© 2021 V2EX