V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Vimax
V2EX  ›  Java

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

  •  
  •   Vimax · 2020-07-14 15:13:54 +08:00 · 10863 次点击
    这是一个创建于 1597 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    请求成功

    • GET 200 OK
    • POST 201 Created
    • PUT 202 Accepted
    • DELETE 204 No Content

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

    是返回 404 not found 吗?

    另外一个问题

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

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

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

    • GET application/x-www-form-urlencoded
    • POST [ "application/json;charset=UTF-8" ]
    • PUT [ "application/json;charset=UTF-8" ]
    • DELETE application/x-www-form-urlencoded
    132 条回复    2020-07-16 10:37:35 +08:00
    1  2  
    lff0305
        101
    lff0305  
       2020-07-15 17:31:28 +08:00
    个人觉得用 200 加上 body 里的信息。
    404 的话不知道是成功了,还是中间什么地方出现了问题(网关,负载均衡)
    hantsy
        102
    hantsy  
       2020-07-15 17:31:40 +08:00
    整个说话跟拉稀一样,还在这里呛人。
    @est
    est
        103
    est  
       2020-07-15 17:34:09 +08:00
    @hantsy 你拉的都是干的,还是粉色的。
    hantsy
        104
    hantsy  
       2020-07-15 17:35:26 +08:00
    @est 我看你挺喜欢的,一上来不管 3721 就全收了。
    est
        105
    est  
       2020-07-15 17:38:30 +08:00
    @hantsy 这位是看拉稀看出 20 年经验了。 👍
    hantsy
        106
    hantsy  
       2020-07-15 17:39:40 +08:00
    @est 被你说中了。
    iseki
        107
    iseki  
       2020-07-15 17:42:18 +08:00 via Android   ❤️ 1
    天天吵这点破事…千万别给出错的请求会 200 就好…也别自己造状态码,相应体内部的错误信息能用 enum 描述的别用莫名其妙的一串数字好不好…
    est
        108
    est  
       2020-07-15 17:43:26 +08:00
    @hantsy 多吃点,不要停,吃习惯了就不呛了。
    iseki
        109
    iseki  
       2020-07-15 17:47:52 +08:00 via Android
    一切请求会 200 简直是在给自己找麻烦…各种麻烦
    hantsy
        110
    hantsy  
       2020-07-15 17:49:50 +08:00
    @est 现在你们这种人我早看就习惯了。

    10 年前国内还有很多软件公司,开发的时候程序员还保留有一点自己的修为,懂什么叫软件品质。现在国内几乎没有软件公司,国内互联网公司基本是资本运作的结果,做出来的东西只要能跑就行了。

    十年前我就不在职场了。
    est
        111
    est  
       2020-07-15 17:55:14 +08:00
    @hantsy 你那么讲究品质,你倒是说说

    > 订单 200 表示存在,404 表示不存在,那已拆分订单如何表示?

    这个 API 的 code 怎么设计好?

    Roy Fielding 还主导设计了 Apache HTTPd 没错吧 ,你这么喜欢舔请问你现在还用这货吗?
    hantsy
        112
    hantsy  
       2020-07-15 17:59:58 +08:00
    》 Roy Fielding 还主导设计了 Apache HTTPd 没错吧

    看来这次说话小心了点,知道说话前查资料了,这个没错啊。有没有人用,自己去 Google 搜索 结果比较一下就知道了。
    est
        113
    est  
       2020-07-15 18:02:27 +08:00
    @hantsy 我不问有不有人用,只问你用不用。毕竟你把别人 20 年前的论文当宝一样耀武扬威呢。

    还有

    > 订单 200 表示存在,404 表示不存在,那已拆分订单如何表示?


    你倒是用你优雅的品质设计一个 RESTful 出来
    iugo
        114
    iugo  
       2020-07-15 18:11:03 +08:00
    @libook

    不是纠结一定要 REST, 而是认为 HTTP 状态码在一些地方应该被使用.

    Web 最初是为了描述网页资源.

    如果一个文章网页曾经存在, 但因为一些原因被删除了.

    客户端是浏览器.

    这时后端返回 404 是不是更好一些?

    ---

    再说 API.

    如果请求 `GET /item?id=123`, 数据库中没这一数据, 这时候状态返回 200, 再给数据不存在的业务代码是合理的.

    但是如果请求 `GET /item/123`, 数据库中没这一数据, 我认为这时候状态返回 404 而不是 200 才是合适的.

    具体用哪种风格好, 我不评论. 只是主题说了 "RESTful 的增删改查成功应该返回什么状态码?", 而不是 "API 的增删改查成功应该返回什么状态码?", 所以主题说的应该是上例中的后者.
    hantsy
        115
    hantsy  
       2020-07-15 18:11:23 +08:00
    从你的话,我又一次感觉到你在一直说 Fielding 博士不如你。

    我写主要写 Java,为什么要用 Apache ?

    对于标准来讲 15 年前的东西现在一点不会过时,一般互联网标准讨论超过 10 年没定好的多的是。


    每个订单有自己的 OrderStatus

    Get /ordres/originalorderid

    200
    {
    orderstatus:
    sublist:[拆分子订单号列表] 当然这里最好是 Level 3, 用 Link
    }
    hantsy
        116
    hantsy  
       2020-07-15 18:12:29 +08:00
    @est 散了吧,不要再 at 我了。
    est
        117
    est  
       2020-07-15 18:19:25 +08:00
    @hantsy 嗯。我最后 at 你一次。orderstatus 和 http status,明明都是表示单一的订单状态,还要套 2 层,老优雅了。
    iugo
        118
    iugo  
       2020-07-15 18:20:35 +08:00
    不是说 REST 多好多好, 大家都该用.

    而是主题问的是 REST, 所以就这个来回答不跑题.

    1. REST 到底好不好用, 这个见仁见智, 但较为老旧简单难以适应复杂需求这点可能更多人认同.
    2. HTTP 状态码到底怎么用, 我认为还是要看情况吧, 所有业务一旦进入处理流程都 200 太绝对了.
    hantsy
        119
    hantsy  
       2020-07-15 18:23:05 +08:00
    @est 数据 State 与 Http Status 有什么关系?
    hantsy
        120
    hantsy  
       2020-07-15 18:27:24 +08:00
    一个订单 10,8 种状态,订单 Oderstatus 只是数据属性 ,只要这个订单存在,返回订单,就可以进去。这东西能和 http status 能扯到一起,我只能服了你。

    以前我很难理解,V 站那么多人说查询就会想 SQL 怎么写,你这思维大概知道了。
    hantsy
        121
    hantsy  
       2020-07-15 18:29:00 +08:00
    还有之前看到一个什么 Redis 事务,同类。牛的病,能够扯到猪身上去了。
    hantsy
        122
    hantsy  
       2020-07-15 18:38:23 +08:00
    我的例子中,https://github.com/hantsy/spring-reactive-jwt-sample/blob/master/src/main/java/com/example/demo/domain/Post.java

    也有 DRAFT,PUBLISHED 两个状态,这能跟 Http Status 扯上关系。

    这种思维闻所未闻。今天算是开一个眼界了,Fielding 原来这么不受待见,还不如 V 站一个小喷壶,英文都看不懂的情况非要说他说的资源是文件。
    est
        123
    est  
       2020-07-15 18:49:55 +08:00
    @iugo 我的观点是,所有业务一旦进入流程都 200 是一个很好的设计。404 只能表示这个 API 入口被删了。不能表示资源不见了。 那种把物品 id 放到 URL 路径一部分的做法,RESTful 一时爽,nginx 日志分析火葬场。
    libook
        124
    libook  
       2020-07-15 18:53:06 +08:00
    @iugo 题主问的是 RESTful 应该返回什么状态码,我的态度很明确,返回啥都行,因为根本就不是 REST 的核心概念所关心的。
    但是 HTTP 协议关心这个,所以老老实实按照 W3C 的标准文档来定义返回什么状态码就行了。

    你举的两个例子可以是你的一种实践方案,如果适合你的业务的话是完全可以用的。

    所以。。。真没必要跟我这里强调应该用哪种,因为我压根没有说哪种好哪种不好,都是看实际用起来是否好用。
    bestwaytowait
        125
    bestwaytowait  
       2020-07-15 19:27:29 +08:00
    赶紧别用 restful 了……省着吵架;

    我记得有个 GraphQL,不知道是不是摆脱了这种问题……
    hantsy
        126
    hantsy  
       2020-07-15 21:01:49 +08:00
    @bestwaytowait GraphQL 可以解决一部分 REST 上的缺陷问题。

    从某些角度,我感觉 GraphQL 是弥补了 REST 返回数据颗粒控制上问题。以前我一些做法是尽可能让 REST API 足够细, 返回数据足够细,结果面临的问题是,要么前端一个页面往往要调用多次聚合数据显示 (当然这和国内的前端水平也有很大关系,如果按 React 的 Presenter/Container 模式,页面可以组件切得足够细,逻辑和展示完全可以分离,而我看到的代码很多一个页面对应一个巨无霸组件解决),要么另外在服务器加一个 Gateway 去按需求聚合数据。

    如果按 REST 思维去度量 GraphQL,GraphQL 完全违背了 REST 。一句话,GraphQL 不是 REST,而是为 API 开发提供了另外一种选择。
    jones2000
        127
    jones2000  
       2020-07-15 23:02:38 +08:00
    @hantsy 这个是一个页面版的数据库查询分析器用来给学生学习数据库课程的, 学生通过页面编辑器直接写 sql 查询,创建表 等数据库的相关操作, 允许写错误的 sql 语句,通过执行报错在前端显示出来。如果直接就提示错误, 没有任何错误信息,学生根本就不知道怎么修正他的 sql 语句
    kalista
        128
    kalista  
       2020-07-16 01:23:58 +08:00 via Android
    我们也是全部返回 200,我这个菜鸟倒是挺好理解,不过也遇到过特殊情况需要使用 40x 就是
    hyperbin
        129
    hyperbin  
       2020-07-16 08:20:17 +08:00 via Android
    @yaphets666 别告诉我 2020 年了还没用 HTTPS
    cruii
        130
    cruii  
       2020-07-16 09:47:19 +08:00
    @zsdroid
    那干脆用你的业务码取代 HTTP Code 吧。反正最后都是看你的业务码。对你来说,HTTP Code 无非就是个摆设。勿回。
    smartqq
        131
    smartqq  
       2020-07-16 10:13:19 +08:00
    统一返回 200 是国情 没毛病的
    很久以前返回 404 等 code 会被运营商重定向。。。
    iugo
        132
    iugo  
       2020-07-16 10:37:35 +08:00
    虽然对于这种人造的, 有历史的东西, 争论没有意义. 但我觉得在这个过程中, 我们能对什么是更好的有更多的理解. 我们的讨论都是在表述自己的理解, 不存在说服谁的问题.

    以下都是我的想法, 不是客观正确的, 是我认为正确的. 不是要说服谁, 是想表达让大家参考, 也期待大家有相关的分享让我参考. 讨论的目的只是互通有无.

    ## 关于是否使用 REST

    首先, 如果不用 REST, 进入业务后都返回 200 是一种我可以接受的设计. 这点我觉得没有问题. 我的个人经验是, 交互业务重时, REST 捉襟见肘.

    ## 关于什么是 HTTP Client

    但当我作为前端时, 我可能更希望大家去使用 HTTP 状态码而不是不去用. 因为我这个前端不认为 4xx 错误码是给前端代码用的, 而是给用户的. Client 可能表示前端代码, 浏览器, 用户. 前端也是 user agent, 和浏览器一样, client 应该主要代表 user, 而不是 user agent.

    ## 是否要用 HTTP 状态码

    基于与 HTTP Client 的想法, 所以我倾向于 API 使用更多的 HTTP 状态码.

    ## 关于 REST 最初设计的想法 (暂存草稿)

    https://v2ex.com/t/689938?p=1#r_9251862

    > The key abstraction of information in REST is a resource.

    - HTTP 协议有状态码设计.

    > Although those implementations reflect many of the design constraints of REST, having been developed by people familiar with the Web's architectural design and rationale, the real WWW architecture is independent of any single implementation. The modern Web is defined by its standard interfaces and protocols, not how those interfaces and protocols are implemented in a given piece of software.

    - REST 存在一些设计约束, 这些设计约束来源于当时的 WWW 实现(比如 libwww, 在现在我已经不知道这是个什么东西了, 应该类似于 HTTP 服务端与浏览器的结合吧).
    - WWW 是独立的, 不受制于任何软件设计实现, REST 也是一种利用 WWW 实现业务的设计实现, 不应该被排除, 大家可以考虑考虑.
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3435 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 11:10 · PVG 19:10 · LAX 03:10 · JFK 06:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.