后端 response code 该怎样返回?

2021-10-18 18:42:01 +08:00
 hlayk

前提:前后端定义了通用的数据结构包含 data,mseeage,code,success 这几个基本字段用来去接收后端接口的数据。

场景:某一接口客户端发出的请求出现参数或后端校验等业务错误

问题:后端 http 层的 response code 应该返回什么? 200 还是非 200 ?(呆过的不同公司有着不一样的习惯)

问题来源:主要是用的网络请求框架( retrofit ),对于小于 200 或者大于等于 300 的 response code 直接抛了异常,但我并不想对这异常再进行解析 HttpException 中的 response body 解析出上述的数据结构,所以我拦截了 response 改了 response code 为 200 。这样的话,我对于 response code 无论是什么,我都可以同样的对象解析。

4908 次点击
所在节点    程序员
44 条回复
Rache1
2021-10-19 09:27:37 +08:00
看前端,可以让前端传个指定 header 来给所有响应都返回 200,默认按照 HTTP CODE 返回。

实际 response 里面的 code,我之前的做法都是三位 HTTP CODE + 三位业务 CODE 。 比如 400001,400 就是对应 HTTP CODE 中的请求参数有问题,001 就是可能是某个字段或者某个过程没有校验通过。
2i2Re2PLMaDnghL
2021-10-19 10:19:56 +08:00
作为 Web 实质标准的 JavaScript,其 Fetch API 对于 4xx 5xx 都不抛错,你换个正常点的请求框架吧。

有人说,并不一定非得用 HTTP status code 才叫 RESTful,甚至不一定需要 HTTP

另外,我不推荐 "success": true/false,而采用 "status": "OK"/"NOT_FOUND"/... ,这样塞更多的实质状态比较方便。
不要用「码」,用「符号」。码是在计算机性能不足的情况下的妥协,符号才是正统。

@yidinghe 这个问题本应当可以快速地从 404 text/html 还是 404 application/json 区分出来
oxromantic
2021-10-19 11:05:41 +08:00
@2i2Re2PLMaDnghL retrofit 你居然让换个正常点的框架?类似 ios 的 alamofire,都是 top1 的框架,都不建议在非 200 的 http status code 里处理业务逻辑
hlayk
2021-10-19 11:23:52 +08:00
@oxromantic 大家又不是都是搞移动端的 不知道这些库也正常
abcbuzhiming
2021-10-19 11:40:44 +08:00
关于 code 返回什么,一直有争议,有人认为就应该用 http 的 status code,所以他们返回 200 ;而另外一群人比如我就认为 code 是业务码,和 http status 无关,正常下就是 0,非 0 就是错误,并且附带错误信息 msg 。
lewinlan
2021-10-19 12:55:17 +08:00
业务内的异常就装在 code 里,http 给 200 。
网络,框架等非业务的异常,才用 400/500 的 http 。

把资源装进 data,这个事情就已经不 REST 了
2i2Re2PLMaDnghL
2021-10-19 13:01:28 +08:00
@oxromantic 这个建议是为了 HTTP 以外的一些协议没有 status code 所以将 HTTP 降级。这就好比因为很多网站不支持 bbcode 就要求现在在用 bbcode 的网站一律不允许使用 bbcode 一样可笑。
oxromantic
2021-10-19 13:46:39 +08:00
@2i2Re2PLMaDnghL 你搞错了,这些 status code 并不是你应用独占的,和容器抢这些 status code,就会给前端引入不确定性的混乱,而没有个前端定义一个可以直接判断属于业务数据的基础规则
2i2Re2PLMaDnghL
2021-10-19 14:26:06 +08:00
@oxromantic 那就更诡异了,容器为什么要抢 status code ?它连 HTTP 都不 aware
penll
2021-10-19 14:30:42 +08:00
code 直接英文字母,方便后端定位问题。
message 只是给用户看得友好信息
oxromantic
2021-10-19 16:04:21 +08:00
@2i2Re2PLMaDnghL pcf/k8s 都会啊,可以了解下
unco020511
2021-10-19 16:45:27 +08:00
两种都可以,看你们怎么理解,可以把 http 单纯当做一个数据传输协议,只要数据传输成功一律 httpcode200,然后定义自己的业务 code.同时因为 httpcode 也是语义化的,也可以使用仅使用 httpcode 一套来表示传输及业务状态
ychost
2021-10-19 17:50:52 +08:00
code 建议用字符串,这样方便两个调试,httpCode 一律 200
2i2Re2PLMaDnghL
2021-10-20 09:40:23 +08:00
@oxromantic 首先,PCF 似乎是 VMWare 的多个不同的东西的品牌名称?具体没搜到。k8s 是编排工具而不是容器。
其次,各类 load balancer 看上去也并不会抢 status code,而是尝试中间捕获 status code 来判断服务健康状况来安排重启和替换请求,这种情况下会修改的可不止是 status code,而是整个响应都会被替换。
xingheng
2021-10-20 13:27:32 +08:00
@Jooooooooo #2 我要是看见谁用 0 标识自定义 code 为成功的话一定往死里骂,int 的默认值(在很多语言里很多都)是 0,本来就是取个 int 的事情非要我区分到底是因为服务器本身返回的傻逼 0 还是 code 值取不到用了 int 默认值。
oxromantic
2021-10-20 13:55:27 +08:00
@2i2Re2PLMaDnghL pcf 是比较早的商业容器实现,大概被 vmware 收购了,具体没了解,既然你提到整个响应都会被替换,这就是我之前描述的场景,你以为的业务 response,实际已经被替换了,所以不能光靠 http status code 来处理业务,还需要加额外的逻辑,但既然加额外的逻辑,何必还抱死 http status code ;另外,我所谓的容器是广义的,譬如远古的 war 跑在 tomcat 里,那么 tomcat 就是 war 的容器,tomcat 自己也会用到 http status code 表达自己的状态
Jooooooooo
2021-10-20 14:45:16 +08:00
@xingheng 你担忧的问题在这里不是问题. 用了就知道.
2i2Re2PLMaDnghL
2021-10-20 15:42:22 +08:00
@oxromantic 替换应是对前端透明的,不需要额外逻辑。
Tomcat 算是混合了一个编排工具?
编排工具如何返回它自身的信息应当是可以自定义的,而不是埋暗雷(但暗雷见得多了,Flask 也暗雷)。不过现在问题是科技树还没点到动态编译语言。

当然,如 #26,放 data 已经不 REST 了,本来的处理上就是 body 就是全部内容或者没有内容,甚至,尽管不那么典型,这个 URL 逻辑上是可以 cd 进去的(类似 WebDAV )。
应当将这种状态和其他协议的 code/data 状态进行对应。gemini 更诡异一点(
xingheng
2021-10-20 16:34:24 +08:00
@Jooooooooo #37 不是所有语言都支持 optional type,后端写的接口需要考虑各种语言的使用场景。
bthulu
2021-10-20 17:11:09 +08:00
非对外公开给其他部门或其他公司使用的 API,一律不做任何处理,什么 status, code, msg 都不需要,逻辑成功就返回对象,失败就返回异常信息。前端框架统一对 4XX 错误做下处理,其余什么也不要做。简单就是美

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

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

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

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

© 2021 V2EX