想给所有的业务异常一个统一固定的 HTTP 状态码,用什么合适? 403? 409? 422?

2023-09-01 10:08:49 +08:00
 param

http 状态码能不能用-1 的。

不要 200 ,那样我就要在 response 再包一层。 我想给业务异常统一固定的 HTTP 状态码,例如 403 ,那么我遇到 403 才会拆开看里面的业务异常,在 403 的 response 里返回大写字母格式的错误码以及 err msg 。如果遇到 200 ,就默认没有异常,不需要拆开了。

业务异常指的是,诸如「未完成的订单不允许评论」之类的

403 经常被认为是「权限不够,换个身份操作就可以成功」的意思,但它其实应该是「 forbidden 」,没有说明是权限不够而 forbidden ,或者其他原因的 forbidden 。具体原因还是可以在 body 里看。

这个问题在这里好像吵得很厉害,我不想对 200 再封一层,同时也需要自定义的状态码,这完全不矛盾呀。

2891 次点击
所在节点    问与答
32 条回复
yolee599
2023-09-01 13:09:56 +08:00
http 请求到达了你业务程序,你就应该返回 200 ,业务代码再在 body 中单独定义
sujin190
2023-09-01 13:12:42 +08:00
body 结构不一致才是真的坑死人,每次遇到这种都觉得这么干的人真是脑子进水了
Masoud2023
2023-09-01 13:36:48 +08:00
非要用 http 状态码就老老实实 RFC

不要自己造状态码,body 里 errorCode 不磕碜,自己乱造小心到时候各种中间件找你麻烦
clf
2023-09-01 13:41:16 +08:00
只用标准的 http 状态码,业务异常则是 Http 200 ,但 body 的 code 返回其他的。
fivesmallq
2023-09-01 13:59:02 +08:00
参考 stripe 设计 https://stripe.com/docs/api/errors?lang=curl

```sh
curl https://api.stripe.com/v1/payouts \
-u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
-d amount=11a00 \
-d currency=usd
{
"error": {
"code": "parameter_invalid_integer",
"doc_url": "https://stripe.com/docs/error-codes/parameter-invalid-integer",
"message": "Invalid integer: 11a00",
"param": "amount",
"request_log_url": "https://dashboard.stripe.com/test/logs/req_H7WCCMvEpRyv9s?t=1693547819",
"type": "invalid_request_error"
}
}

```

也可以不加 error 那一层,直接返回里面的内容。
scung
2023-09-01 14:28:54 +08:00
用 HTTP 418 状态码😊
TPOB
2023-09-01 15:47:04 +08:00
现在大家的用法其实是把 http 当传输层协议在用,那 http 的状态码就应该统一是 200 (传输没有异常)。业务的异常就放在 body 里面才对
cylx3124
2023-09-01 17:32:10 +08:00
https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/http/HttpStatusCode.java#L39C2-L77C20

https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/http/HttpStatus.java#L36C1-L424C95

Spring 文档给出了对的 http code 详细解释,建议先看一下 Spring 对 http status 的定义,然后思考下 4xx 客户端异常、5xx 服务端异常和业务异常的区别,想明白以后你的问题自己心里应该就会有答案。
zhzy0077
2023-09-01 18:22:27 +08:00
要么你就正经按照错误类型去找最合适的 http code ,虽然对于绝大多数业务 4xx 和 5xx 是绝对不够用的。
要么你就干脆一律 200 ,然后用 flag 去标有没有成功。
一半一半的容易把自己和同事绕进去
wu00
2023-09-01 18:51:03 +08:00
符合规范的只用了这几个,基本上是网关层/代码底层控制的
401 ,403 ,404 ,415 ,502 ,500

开发中约定俗成的由开发人员控制的就两个
200 ,成功一律 200 ,不区分 201 、204 等等
400 ,业务异常一律 400 ,包一个对象定义异常类型{errorCode, errorData, errorMessage}

真要按照标准规范无疑是找罪受...
agagega
2023-09-01 18:56:19 +08:00
以前接手过一个 php 项目,错误统一 404…
param
2023-09-07 23:25:49 +08:00
@CodeCodeStudy 没错啊,我不是说了用自定义的业务状态码吗。只是客户端要在遇到业务异常时才需要去看业务状态码,所以需要一个 http 状态码来表示出现了业务异常。

@iOCZ 我不是已经区分了吗。我 http 状态码只是用来标记有没有出现业务异常,而具体的业务异常肯定是用业务状态码表示啊。

@dallaslu 我不是说了把业务异常放在 body 里定义了吗。只是我需要先判断是否成功,再决定要不要拆开 body 看业务异常。如果是 200 我就不用拆开看 body 里的东西了。

@TPOB 对啊,业务异常放在 body 啊。现在要用一个 http 状态码表示业务是否成功,不成功的话就看 body 里给了什么业务异常。

楼上已经说了,用 400 了。

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

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

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

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

© 2021 V2EX