RESTful 的增删改查成功应该返回什么状态码?

2020-07-14 15:13:54 +08:00
 Vimax

RESTful 的 GET POST PUT DELETE 如果操作成功应该返回什么状态码呢?

用 200,201,202,204 代表 4 种请求的成功合适吗?

请求成功

如果 GET POST PUT   DETELE 请求,数据库执行结果都为 0.又如何返回 HTTP 状态码呢?

是返回 404 not found 吗?

另外一个问题

请求方式的数据类型: GET 和 DELETE 是否[不能]或[不推荐]使用 JSON 数据的形式.

前端使用的是 VUE axios 发送请求,之前 DELETE 发送 JSON 数据,后端无法接收到.

目前 4 种请求方式对应使用的数据类型是:

10684 次点击
所在节点    Java
132 条回复
binux
2020-07-15 11:25:18 +08:00
@yaphets666 “直接被浏览器处理了”???
还有现在还不上 https 的公司就别呆了。
libook
2020-07-15 11:30:20 +08:00
HTTP 是通信协议,建议将协议上的状态与业务上的状态分开,所以 HTTP 的返回状态码最好严格按照 HTTP 标准来使用,涉及到业务状态的最好在返回结果里用额外的状态标识来标识。

比如 DELETE,服务器执行成功,且返回 Body 有内容,则返回 HTTP 状态码 200 (其他情况参考 2xx 段各个状态码的定义),返回的 Body 里用字段或对象来体现业务上的状态,是有记录且成功删除了,还是成功执行了但无可删除记录,还是删除错误 1 、删除错误 2 等等。
4xx 段在标准中表示的是因客户端错误导致的非预期的请求,这就看你如何定义这个 API 了,比如 API 的 URI 被视为一个确定的资源,如 /user/12345,那么业务上可以定义为使用 DELETE 方法是建立在 ID 为 12345 的这个 user 资源存在的基础上的,那么 HTTP 协议上可以首先考虑这个资源是否存在,如果不存在的话,业务上可以认为这个资源不存在客户端就不应该发出这个请求,就按照 HTTP 标准返回 404,告诉客户端它发出的这个请求有问题。

这些都不是固定死的,关键是一套系统的 API 应该有统一的一套自己的标准。
比如你定义除了创建以外,任何对于资源的直接操作都应该基于资源存在的基础,资源不存在一律返回 404 状态。
然后系统内所有 API 都按照这个标准来设计就可以了。
REST 只是一套帮助你设计自己系统 API 标准的思想,最终还是要为业务服务的,如果其思想与业务需求相矛盾,就没必要硬上 REST 风格。
wangyzj
2020-07-15 11:32:01 +08:00
200
libook
2020-07-15 11:37:52 +08:00
可能写得有点长,核心没表达清楚。

返回 404 是因为“需要告诉客户端它犯了个(请求的资源不存在的)错误”,而不是因为“这个资源不存在”;同样的,返回 200 是因为“需要告诉客户端这个请求成功了(且不属于其他 2xx 状态码的情况)”,而不是因为“业务成功了”。

可以细细品一下。
baiyi
2020-07-15 11:38:31 +08:00
@bigWolf999 #28 query 过多且过于复杂时,可以使用查询语言类协议,比如 GraphQL
RJH
2020-07-15 15:03:12 +08:00
直接 200,然后在响应体里面返回定义业务状态码,不懂就参考微信、阿里的接口
zsdroid
2020-07-15 15:14:40 +08:00
别人来讨论问题,总有一些人以为自己很牛逼,一上来就喷。别人反喷他一下,他就急了。
zsdroid
2020-07-15 15:19:42 +08:00
iugo
2020-07-15 15:27:27 +08:00
@libook

- 需要告诉客户端它犯了个(请求的资源不存在的)错误
- 这个资源不存在

我觉得这两个难以区分.

我认为我理解你想要表达的, 就是协议统统 200, 不需要 404, 除非 API 路由都不对, 才会 404.

但这种设计不符合 RESTful, 这里不是说 RESTful 绝对正确, 而是不符合 RESTful.
iugo
2020-07-15 15:29:36 +08:00
如果把 HTTP 状态码当作后端错误代码的分类, 这样似乎就很好理解.

我是不建议弃用 HTTP 状态码, 只用 200 的.
frankwei777
2020-07-15 15:44:04 +08:00
我前端 成功只见过 200
markliu2013
2020-07-15 15:44:15 +08:00
@hantsy

/posts/anoneexistingpost 是一个不存在的 Post
/users/noneexistignuser 是一个不存在的 User
/products/noneexiting 是一个不存在的产品
/orders/noneexiting 是一个不存在的订单

这种返回 404 是最佳实践吗?我觉得 404 是告诉客户端,他请求的接口不存在,但是 /posts/这个接口是存在。比如本来一个 user 资源是存在的,但是被另一个用户删除了,这时候在请求就会 404,客户端就会感觉莫名其妙。

比如在一个 MVC 的架构里面,请求 users.php?id=1,但是 id 为 1 的 user 不存在,这时候能返回 404 吗?
hantsy
2020-07-15 15:53:04 +08:00
@markliu2013

/posts/<id 或者 id 对等物,比如 Slug>, 如果这个 ID 不存在,返回 404, 这个意思。你还在武汉?微信或者邮件聊吧。
hantsy
2020-07-15 15:57:57 +08:00
@markliu2013 或者你看直接代码吧。
markliu2013
2020-07-15 16:01:41 +08:00
技术问题就这里聊聊吧。
我的意思是 404 在这里是否是最佳实践的设计。因为这个接口本身是存在的,也去数据库查询了,但是查询结果是空集合。

我找到了这个问题:
https://stackoverflow.com/questions/11746894/what-is-the-proper-rest-response-code-for-a-valid-request-but-an-empty-data
目前有说 404,但是也有说用 204 或者 200
hantsy
2020-07-15 16:02:12 +08:00
>404 Not Found: The requested resource could not be found but may be available again in the future.

就是表示你访问的时候资源不存在。
hantsy
2020-07-15 16:04:51 +08:00
@markliu2013 你说的 Users.php? 的情况是集合,永远返回 200,即使是空的 Body,除非有其它逻辑出玩异常要处理。

posts/:id 表示单个资源。
hantsy
2020-07-15 16:06:28 +08:00
目前我所用的 404 都是会定位到单个资源上操作上 get, put, delete,找不到的时候都返回 404 。
hantsy
2020-07-15 16:10:33 +08:00
集合查询结果为空用 204 感觉有点牵强,用 json 的话,它是一个空的数据 [] ,这个内容长度不是 0 。
zsdroid
2020-07-15 16:18:45 +08:00
@cruii HTTP 规范告诉你请求成功了,结果后端告诉你业务出错了。没毛病吧。
难道实际上请求成功了,却告诉你请求失败了才对?

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

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

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

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

© 2021 V2EX