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

Restful API 资源未找到应该返回什么状态码?

  •  
  •   zuoakang · 2019-06-27 21:20:04 +08:00 via Android · 12070 次点击
    这是一个创建于 1754 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求是这样的: 查询某个用户是否存在,GET users/zhangshan

    我这边使用的是 drf 框架,为了与框架统一,资源未找到返回的状态码都是 404。

    与我这边对接的是 java 后台,他们觉得返回 404 会被他们 try cache,认为是请求参数有问题或者 URL 出错,程序不往下走了,而返回 200,response 为空,程序会往下走,而且知道 zhangshan 这个对象为空。

    大家觉得资源不存在应该返回什么状态码呢?

    93 条回复    2019-07-01 14:36:25 +08:00
    learnshare
        1
    learnshare  
       2019-06-27 21:23:19 +08:00   ❤️ 1
    404 就是这么用的,出错需要写出错的处理逻辑,程序不走了可不行
    chi1st
        2
    chi1st  
       2019-06-27 21:29:54 +08:00
    正好前两天因为这个问题和对接方争论了一下,他们认为 404 是错误,让我返回 200,对于 Restful 的规范来说确实是应该返回 404,所以我并没有去修改。但是我决定以后的接口都返回 200 了,因为公司大部分人都是按照 200 来返回的,还是遵循他们的约定比较好。

    以下链接有人也对这个问题进行的讨论
    https://segmentfault.com/q/1010000017048482/a-1020000017049993
    k9982874
        3
    k9982874  
       2019-06-27 21:33:04 +08:00 via iPhone
    实际操作还是返回 200,在 response body 里再定义错误码,前端逻辑实现错误处理。
    原因很简单,开发到后面你会发现那点 http error code 根本不够用。
    loading
        4
    loading  
       2019-06-27 21:39:00 +08:00 via Android   ❤️ 1
    如果你服务器正确响应都是 200,然后 json 里面有字段,我一般是:
    state:200,msg:done
    state:404,msg:not found
    一个是对应状态号,一个是返回的人类信息。
    zqx
        5
    zqx  
       2019-06-27 21:40:50 +08:00 via Android
    我们接口有上千个状态......restful 根本不够用啊
    IvanLi127
        6
    IvanLi127  
       2019-06-27 21:44:51 +08:00 via Android
    404,资源未找到本来就是异常情况。
    dobelee
        7
    dobelee  
       2019-06-27 21:47:33 +08:00 via Android
    个人喜好,状态码 200,协议码与应用码分离。
    just1
        8
    just1  
       2019-06-27 21:50:36 +08:00
    @IvanLi127 #6 查询不到东西和资源未找到可不是一个概念啊,空的服务器也是 404...
    kidlj
        9
    kidlj  
       2019-06-27 21:51:21 +08:00
    请求是 GET /users/zhangshan:

    restful url 未找到,返回 404。如果 /users/zhangshan 未定义,返回 404.

    你这个例子是 url 找到了,而且执行了 handler,只是业务资源为空,返回 200,并自定义错误码标识即可。
    PDX
        10
    PDX  
       2019-06-27 21:54:02 +08:00 via iPhone
    今天正好在考虑这个问题,看到你的帖子真的太好了
    est
        11
    est  
       2019-06-27 22:01:12 +08:00
    200

    如果有客户端不小心 URL 拼错了,GET user/zhangshan

    这个时候你该返回 404 呢还是返回 404 呢?

    RESTful 就是代码写得少的人拍脑袋的作品。没错我说的就是 Roy Fielding。他在 2000 的 PhD 论文里发明了 RESTful 被人当成宝捡到。后来他最得意的作品在 Adobe 做的 ColdFusion。。。
    billlee
        12
    billlee  
       2019-06-27 22:04:08 +08:00   ❤️ 12
    你牛就返回 404, 对方牛就返回 200.
    IvanLi127
        13
    IvanLi127  
       2019-06-27 22:08:45 +08:00 via Android
    @just1 我是认为 404 等于这个资源不存在,如果数据集是空的,应该返回空数组,单个资源是空的,那应该返回空资源(允许为空的情况下),资源找不到就返回 404。要是 url 压根没定义,那这是口锅了。。。
    johnniang
        14
    johnniang  
       2019-06-27 22:13:22 +08:00
    不仅仅状态码需要返回 404,而且还需要返回一个统一错误返回体: {code: 404, message: "The entity was not found", data: 12345678}。

    这样即符合了 RESTful 风格,也解决了状态码不够用和状态混淆的问题。
    IvanLi127
        15
    IvanLi127  
       2019-06-27 22:13:59 +08:00 via Android
    @est 面向资源,没定义也就等于没资源。如果只看 http 状态码就想知道具体啥问题,那在响应体里写似乎也是多余了。如果是想在响应体里看,那多返回个错误信息不就好了。最后,出现这堆问题是不是 http 的锅? 手动狗头保命
    zuoakang
        16
    zuoakang  
    OP
       2019-06-27 22:19:11 +08:00 via Android
    @johnniang 返回体包含你说的数据,就是这个状态码是 200 还是应该是 404 ?
    wu67
        17
    wu67  
       2019-06-27 22:22:44 +08:00
    按我的理解, API 不存在 /拼错字的时候 404, 这是 http 状态.

    没数据应该返回’空值’, 此时 http 应该是 200, 但你返回的 data 应该应该带 code 告知客户端状态为 404, 或者也返回 200 也行, 最后加上 msg 告知数据描述.

    反正最好有一套对应的 code 和 msg, 由客户端判空进而显示 code、msg
    df0618
        18
    df0618  
       2019-06-27 22:22:46 +08:00
    @zuoakang 返回 404,body 带错误信息

    不过实际上有很多项目都是返回 200 的,说白了就是谁话语权大谁说了算
    est
        19
    est  
       2019-06-27 22:24:20 +08:00
    @IvanLi127 而且把资源 ID 放在 URL 里的行为我是很不理解的。log 里做过滤得上正则。。。
    woscaizi
        20
    woscaizi  
       2019-06-27 22:24:22 +08:00 via iPhone
    404 资源未找到指的是 url 未找到吧。
    我觉得应该用 200,然后通过自定的状态码来标示错误。
    Varobjs
        21
    Varobjs  
       2019-06-27 22:30:55 +08:00 via Android
    try catch 住,是因为偷懒,把所有非 200 的报错了。
    404 不是请求参数错误,请求参数有 400 可以表示
    其实调用方不管什么,都要写很多处理啊,这种扯皮只有一个,两边不统一,不想改,懒。
    df0618
        22
    df0618  
       2019-06-27 22:34:18 +08:00   ❤️ 1
    @zuoakang 比如说,github 的 Api 是这样的
    request: https://api.github.com/repos/aspnet/unknownrepo
    response: code 404
    {
    "message": "Not Found",
    "documentation_url": "https://developer.github.com/v3/repos/#get"
    }

    这是仓库不存在的情况

    request: https://api.github.com/unknown
    response: code 404
    {
    "message": "Not Found",
    "documentation_url": "https://developer.github.com/v3"
    }

    这是资源不存在(url 错误)的情况
    mamian
        23
    mamian  
       2019-06-27 22:34:34 +08:00   ❤️ 2
    就算你接口正常返回 200 对方也需要 try catch,不使用 try catch 才是偷懒
    Varobjs
        24
    Varobjs  
       2019-06-27 22:35:58 +08:00 via Android   ❤️ 1
    如果 URL 是 users/zhangsan,写出 user/zhangsan 我觉得应该返回 404,没有疑问。
    如果应该 zhangsan 不在数据库中,还是返回 200 + 具体 json 内容吧,
    两个不能有歧义
    johnniang
        25
    johnniang  
       2019-06-27 22:49:00 +08:00
    @zuoakang 接口响应 404,返回体中的都是一些自定义的内容,随意~
    broadliyn
        26
    broadliyn  
       2019-06-27 22:58:13 +08:00
    没必要把 restful 奉为圭臬,等你系统做大做复杂了,restful 怎么设计 url 符合规范会把你搞得纠结不已。
    普通 get/post 完全能满足需求。

    至于你说的 http status。我只想说,这个完全就是个人喜好 /团队规范的问题。
    就个人来说,我喜欢 error_code 的方式来表述业务逻辑上边的错误,类似根据 id 获取资源不存在、用户余额不足等等都属于业务异常这个范畴。

    http status 是用在什么地方呢?我一般会用在请求还没进入业务代码的这一层,比如我用的是 spring boot,前边有 nginx 做前端,nginx 上边的 403 无权限、500 内部服务器错误、502 网关异常、以及 spring boot 404 路径不存在、400 requestparam 参数不符合格式、405 method not support 等这类没有进入 controller 业务逻辑代码的错误统一使用 http status 做表述。
    zhilincom
        27
    zhilincom  
       2019-06-27 23:13:15 +08:00
    @zqx 上千个状态?不知道你们是怎么管理的?配置文件?写成枚举?用的时候不知道用哪个怎么办?如何防止重复定义?非常好奇。
    Takamine
        28
    Takamine  
       2019-06-27 23:16:04 +08:00
    不要单纯用状态码来做这个(也完全不够用)。
    只要是这次请求成功那么 http 返回的状态码就是 200,具体业务问题的返回码放在 response 里,用自定义的业务码表。
    broadliyn
        29
    broadliyn  
       2019-06-27 23:17:28 +08:00   ❤️ 3
    另外再补充一下为什么会将请求状态分为 http status 和 error code 自定义错误码两级,是因为在请求没有进入到业务 controller 时,请求可能会经过 waf 高防、nginx squid 等不同网关,每一个网关都可能会出错,而且每一个网关返回 http status 时,他们的格式都是不尽相同的,有的是 html、有的是 json、有的是 plain text,前端这边没办法做统一解析处理,因此对于在没有进入 controller 业务层以前的非 200 status,说明这次请求是失败的,前端这边只能根据 status 做粗的分类进行用户提示。

    如果 http status 为 200,说明请求能顺利进入 controller 层,那么这时候返回的 json 格式完全能保证由开发者控制,前端也能顺利解析。

    举个例子,某个 url 路径 GET /api/user/1 , 产品需求是,如果没有查找到这个 id 的用户,那么前端展示后端返回的错误提示。

    在整个 http 请求过程中,出现 404 的地方可能会有哪些?
    1. nginx 没有配置正确,返回了 404 的错误,response body 是 html 格式的 not found
    2. 业务代码没有找到 id 为 1 的用户,返回了 404 错误,response body 是 json:{"code":-1,"msg":"用户未找到"}
    3. CDN 回源失败,返回 404 错误,response body 是 html 格式的 404 页面
    等等等...

    假设发生了 404 错误,前端 js 代码 onerror=(resp)=>{if(resp.status==404) {....}},这时候你需要展示 404 相关的错误,你改怎么展示?格式内容不定,完全无法解析。

    如果我们把上边的 2,改成 http status=200,前端判断到 status==200,那么就可以放心大胆的根据 code 和 msg 去做数据展示和错误展示,因为只要是 status==200 的,完全能保证返回的内容格式是预期的。


    restful 提出来的时间是 2000 年,到现在已经快 20 年了,现代互联网云服务的 web 服务器架构和 20 年前已经相差很大了,
    http 承载了更多的复杂业务和功能,已经不是 20 年前 web 1.0 那种 增删改查 PUT DELETE POST GET 就能满足需求了。
    YzSama
        30
    YzSama  
       2019-06-27 23:23:21 +08:00 via iPhone
    其实,前后端的接口可以采用 restful api 设计。但是,服务端接口采用 get/post 比较好。然后就是响应状态码就 200。URL 路径设计可以参考 restful 设计。微信好像就是这么干
    AlloVince
        31
    AlloVince  
       2019-06-28 00:05:13 +08:00   ❤️ 2
    理论上应该返回 404

    产生这个争执的根本原因是客户端并没有针对 RESTFul API 调整自己的处理逻辑

    几年前写过一个客户端处理 RESTFul API 的流程伪代码,如果真的是严谨的 RESTFul API,客户端应该按如下流程处理异常

    https://gist.github.com/AlloVince/4ec938b41ee2142333ca

    ```
    //请求成功返回 2XX
    if (statusCode.startWith('2')) {
    //请求成功,处理业务
    } else {
    //5XX 错误,服务器有问题
    if (statusCode.startWith('5')) {
    //响应格式不定,显示网络错误或未知错误给用户
    } elseif (statusCode.startWith('4')) {
    //4XX 错误,输入有问题
    //4XX 错误后端必须保证错误格式
    res = json_decode(responseBody)
    switch (res.errors[0].message) {
    //客户端需要处理的异常分支
    case 'ERR_USER_MOBILE_CAPTCHA_CHECK_FAILED':
    //验证码错误
    break
    //客户端无法预料的异常分支
    default:
    //打印错误信息
    print res.errors[0].message_human
    }
    } else {
    //未知错误
    }
    }
    ```

    问题在于,这样对服务端和客户端双方人员的要求都很高,需要能理解 RESTFul 的思想,并且一直维护状态码及 API 的约定,这对于人员经常有流动,缺少 Code Review 的项目来说,几乎不可能。而一旦出现了一个例外的 API,客户端处理起来就非常麻烦。所以大部分人都会选择更不容易出错的返回 200

    当然,9012 年了,GraphQL 可以用起来了

    如果对这个话题有兴趣,我的 Blog 有几个相关的 PPT 可供深入了解

    https://avnpc.com/about#%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB-ppt
    YakuMioto
        32
    YakuMioto  
       2019-06-28 00:08:52 +08:00 via Android
    看 Twitter, Github, Facebook
    cuzfinal
        33
    cuzfinal  
       2019-06-28 05:13:28 +08:00 via Android
    看看 github 怎么搞的
    jorneyr
        34
    jorneyr  
       2019-06-28 06:50:06 +08:00
    我们返回 200,响应数据部分为 null,属性 data 是查询的响应数据:
    找不到单个对象: { "code": 200, "success": true, "message": "随缘", "data": null }
    找不到多个对象: { "code": 200, "success": true, "message": "随缘", "data": [] }
    luozic
        35
    luozic  
       2019-06-28 07:03:19 +08:00 via iPhone
    前后一致,不提供给第三方服务可以,否则,这叫制造不标准通讯
    ericgui
        36
    ericgui  
       2019-06-28 07:14:35 +08:00
    我觉得返回 200,然后 data:null . internal_code: 404
    sutra
        37
    sutra  
       2019-06-28 07:32:19 +08:00
    404 with response body, in response body describe the error.
    Imr
        38
    Imr  
       2019-06-28 08:08:07 +08:00 via iPhone
    未找到的肯定是 403,报无权限访问
    baiyi
        39
    baiyi  
       2019-06-28 08:19:55 +08:00
    @est #11 Roy T.Fielding 的得意作品不应该是 http1.1 吗
    janus77
        40
    janus77  
       2019-06-28 08:23:35 +08:00 via iPhone
    那你接口不存在也 404 ?前端如何区分?
    所以 状态码和业务码需要分开。
    jss
        41
    jss  
       2019-06-28 08:36:53 +08:00 via iPhone
    http 的返回状态应该是 200 里面的 error code 是 404 或其他
    justfindu
        42
    justfindu  
       2019-06-28 08:38:46 +08:00
    空应该返回 noContent 呀... 204
    darknoll
        43
    darknoll  
       2019-06-28 08:40:56 +08:00
    啥意思,有了 java 做后台你是干啥的?中间还加个网关?
    m939594960
        44
    m939594960  
       2019-06-28 08:42:21 +08:00
    规范不一定是好的,科学家不一定全是对的,只有最符合你业务,大家写的都开心的规范才是真正有意义的。
    zw1027
        45
    zw1027  
       2019-06-28 09:07:05 +08:00
    http response 200
    json 数据里面写好 code 404 和相应的 message
    这样
    triptipstop
        46
    triptipstop  
       2019-06-28 09:15:45 +08:00
    404

    说状态码不够用的
    那是因为你把逻辑放给客户端实现了
    HangoX
        47
    HangoX  
       2019-06-28 09:20:17 +08:00
    很明显人家不是 rest api 开发的,你们商量吧,毕竟如果多的话,改起来挺麻烦的
    littleshy
        48
    littleshy  
       2019-06-28 09:20:28 +08:00
    没人觉得是 204 吗?
    404 应该是没有这个访问路径。没有内容应该是 204。
    littleshy
        49
    littleshy  
       2019-06-28 09:21:30 +08:00
    @justfindu #42 握手。
    TimPeake
        50
    TimPeake  
       2019-06-28 09:23:03 +08:00
    你都说了 Restful API。
    按照这个标准不应该是 Status Code 为 404 吗
    zachlhb
        51
    zachlhb  
       2019-06-28 09:23:22 +08:00 via Android
    很多前端根本不会用 http status,其实前端发请求完全可以拦截到不是 200 的请求的,但是很多人只会处理 200 响应的请求
    abcbuzhiming
        52
    abcbuzhiming  
       2019-06-28 09:29:07 +08:00   ❤️ 2
    楼主,你太纠结了,首先 Restful API 又不是完美的没有缺陷的体系,其次实际生产环境也没有完美,过于追求贴合理论,有的时候是给自己找不愉快
    annielong
        53
    annielong  
       2019-06-28 09:31:41 +08:00
    404 一般底层 http 用,业务层如果没有找到数据,那也是 http status 返回 200 才有的情况,这种时候不能懒省事用 404
    mamian
        54
    mamian  
       2019-06-28 09:47:33 +08:00
    自己用的感受,Restful 会更规范。前端使用起来会更爽,因为不需要二次判断,直接在 catch 里边写错误处理就好,错误信息和错误码由后端返回,如果状态是 200,就需要前端二次判断。
    starryin
        55
    starryin  
       2019-06-28 09:59:32 +08:00
    用哪种方法都是看团队约定,我只提两点:1. spec 里已经说明了 4xx 的返回同样可以带 message body 详细说明错误,2. 对于运维有大量现成的工具,针对状态码进行统计,分析报告及可视化,你在 message body 里自定义错误码后当然也可以做同样的事情,不过多少要绕一些路
    freakxx
        56
    freakxx  
       2019-06-28 10:05:26 +08:00
    哈哈哈,java 现在给我的印象就是万物皆 200,

    我还是比较支持 404,有需要的话再自己做个 message 和业务 code
    cwm165
        57
    cwm165  
       2019-06-28 10:22:07 +08:00
    这里的返回 code 不应该和 http status code 混起来用。资源未找到可能是你业务代码或者逻辑未覆盖到边界条件,那么这的错误并不是 http 的错误。返回 code 200 在此处只代表本次 http 请求已完成,那具体出错的原因会在 message 给出。
    Huelse
        58
    Huelse  
       2019-06-28 10:28:06 +08:00
    虽然我也比较支持 404,但是这个会在 console 报错误提示的,而且一般来说,400 系的错误属于用户错误。所以最后都选择 200 确保响应后返回 msg
    KyonLi
        59
    KyonLi  
       2019-06-28 10:38:00 +08:00
    用户收藏列表接口,如果用户没有收藏过应该返回 404 还是 200
    sikariba
        60
    sikariba  
       2019-06-28 10:46:30 +08:00
    既然说了是 RESTful,那就应该返回 404,但是明显前端没有适配 RESTful。
    这个帖子挺好,学习了
    DavidNineRoc
        61
    DavidNineRoc  
       2019-06-28 10:46:59 +08:00
    一直使用这种风格
    ![]( )
    BigDogWang
        62
    BigDogWang  
       2019-06-28 10:52:02 +08:00
    返回 200 怎么监控服务呢?
    WilliamYang
        63
    WilliamYang  
       2019-06-28 10:54:52 +08:00
    我采用的是返回 404,并在 response body 里添加 code 和 message,前端可以知道是 url 错误,还是资源找不到
    liukanshan
        64
    liukanshan  
       2019-06-28 12:19:58 +08:00
    按照 http 状态码来说 4xx 是客户端错误 如果没有拼写错误 只是业务上面的逻辑 可返回 200, 另外这仅仅是一个参考 适合当前业务的才是最好的
    suom
        65
    suom  
       2019-06-28 12:26:17 +08:00 via Android
    业务逻辑的资源不存在还是 200 好,不然等业务做大接了 waf 错误码统就废了,运维会吐血。
    chanchan
        66
    chanchan  
       2019-06-28 12:37:52 +08:00
    http status 是描述 http 协议的不是用来描述业务的
    jadec0der
        67
    jadec0der  
       2019-06-28 12:44:32 +08:00   ❤️ 2
    如果是 RESTful,那就应该是 404,用 200 也可以,但是别说自己是 RESTful。
    lamada
        68
    lamada  
       2019-06-28 13:17:36 +08:00
    支持 200,代表接口请求成功,服务是可用的。然后返回的业务字段里包含 404 信息,代表业务请求失败。
    sazima
        69
    sazima  
       2019-06-28 13:22:58 +08:00
    我还是习惯所有的 http 状态码都是 200, drf 封装一下吧.

    {
    'code': 404,
    'msg': 'not found'
    }
    shawndev
        70
    shawndev  
       2019-06-28 13:34:28 +08:00
    这个问题算是 restful 风格的日经帖了,说一下我的看法。

    两种方式都可以,也都不能说是错的,建议按照项目目前的设计使用即可。

    如果要新写项目或者重构项目,推荐状态码统一 200。

    业务的错误很难全部映射到 http 状态码,以至于我们公司后端开发凭空捏造出 6xx 的状态码。

    如果通过 message 区分错误,前端需要展示错误是直接展示 message 吗?如果是,依据错误做特殊处理需要判断 message 吧,message 需要国际化怎么办?
    fhy1994
        71
    fhy1994  
       2019-06-28 13:36:34 +08:00
    @DavidNineRoc #61 一模一样
    darknoll
        72
    darknoll  
       2019-06-28 13:45:47 +08:00
    不是服务端的问题就返回 200,在返回的 json 里面写 404
    meetocean
        73
    meetocean  
       2019-06-28 13:56:16 +08:00
    RESTful API 中使用 HTTP 状态码来表示请求状态。404 的定义:请求的内容不存在。
    如果这个说法是对的,那么找不到资源,都是返回 404 而不是 200。
    Sapp
        74
    Sapp  
       2019-06-28 14:01:11 +08:00
    数组不存在返回空数组(反 null 的就是坑爹),单个资源不存在就别反了 404 吧,或者返回个 null (反回个空 {} 的也是坑爹)
    limuyan44
        75
    limuyan44  
       2019-06-28 14:05:32 +08:00 via Android
    好像都本末倒置了,几十年前的 rest 当宝典一样。。适合项目才是真的好。
    Muninn
        76
    Muninn  
       2019-06-28 14:59:45 +08:00
    https://zhuanlan.zhihu.com/p/57367932

    我写过一篇说这个问题

    在公司合作上,支持谁牛听谁的。

    在事情的道理上,支持跟随大厂和框架的,这个大厂用 404 的多,框架也不会不能处理,我认为属于前端太懒或者太弱。
    index90
        77
    index90  
       2019-06-28 15:50:34 +08:00
    请搜索 Google API Design Guide 并学习
    glues
        78
    glues  
       2019-06-28 16:02:24 +08:00
    404 是 HTTP 协议的状态码,跟 RESTful 有毛关系?
    我发现很多 Java 程序员都搞不清楚 HTTP 协议,主要体现在两点:
    1. status code,除了 200,其他一律都是错误,搞得好像非 200 时就不能发 body 一样
    2. 搞不清楚 content-type,他文档上说返回的 JSON,结果返回的是 text,甚至还有返回的 text 需要你 JSON parse 两次
    libook
        79
    libook  
       2019-06-28 16:44:47 +08:00
    返回状态按照数据层分级,HTTP 层的状态用 HTTP 层状态码来表示,业务层的状态用业务状态码来表示,比如客户端 abc 参数传错了,这在 HTTP 层看来是“客户端错误”,所以应该返回 400 的 HTTP 状态吗,但同时在业务上来说是 abc 参数错误,所以同时返回 Body 应该用业务状态码或者错误信息告诉客户端究竟是哪里错了。

    REST 风格是以资源为中心的,简化接口复杂度,将部分功能降级交由 HTTP 层来表示,对于资源找不到的情况,应该按照 HTTP 的 Not found 状态来表示,即 404 状态码。

    REST 设计风格不是说客户端和服务器一方使用的,而是双方都使用的,客户端不管使用什么语言,都应该选用 REST 友好的请求框架来与服务器的 REST 接口通信,否则就不要使用 REST 风格了,不完全按照 REST 的思想来设计不能享受 REST 带来的好处,甚至可能会适得其反。

    然后从系统可靠性上来看,不管服务端用的到底是不是 REST 设计风格,客户端都应该对所有 HTTP 层的异常做妥善处理,不是抛错误了事,而是应该处理所有错误情况;而在应用 REST 设计风格的时候,要习惯将 404、403、401 等作为“正常”状态来妥善处理,提升系统高可靠性以及用户友好程度。

    最后建议整个开发团队科普一下 HTTP Status Code 标准: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
    表示“成功”的状态是整个 2 段,不只有 200。
    ty89
        80
    ty89  
       2019-06-28 17:13:56 +08:00
    我只好奇一点
    哪些强烈要求返回 404 的,你们是从来没遇到过神仙路由器劫持 404 的情况吗?
    k8ser
        81
    k8ser  
       2019-06-28 17:38:40 +08:00
    drf ? 还真有人用?
    Mithril
        82
    Mithril  
       2019-06-28 17:56:09 +08:00
    @ty89 我们写的代码只应对普通人类使用,神仙们就用神仙写的客户端去吧,手动狗头)
    huangyuhua
        83
    huangyuhua  
       2019-06-28 17:56:14 +08:00   ❤️ 1
    个人感觉业务逻辑上的找不到不应该反应在 http 层面上
    支持 200
    xuanbg
        84
    xuanbg  
       2019-06-28 19:29:37 +08:00
    对于这个情况而言,http 协议的资源是接口,接口有响应,怎么能算没找到资源呢?所以就是应该返回 200
    tyrantZhao
        85
    tyrantZhao  
       2019-06-28 19:43:12 +08:00
    业务上的错误不应该和 http 的错误混淆,所以应该在报文内设置错误码。。。另外,restful 这套规则真是复杂啊,明明很简单的东西 ,搞得这么复杂。。。不知道为什么这么多人推崇。。。
    sin30
        86
    sin30  
       2019-06-29 10:45:41 +08:00   ❤️ 1
    本来这种帖子都是懒得回复的,看懂 HTTP 协议,RESTful 建议和国外各种 api 设计的人,不会问出这种傻问题的。

    但是好奇心让我看完了所有的回复,截止发送此回复时,共有 29 个回复支持使用 404,39 个回复支持用 200。

    看来还是 200 党获胜啊。

    这些 200 党,请问你们仔细研究过 HTTP 协议,看懂理解 RESTful 的思想,读过 Github 的 API 接口么?

    都 9012 年了,还有那么多抱残守缺、不思改变的人,也真是 shame 啊。

    从最开始写 API,就知道用 200,用 get post,写了这么多年不想想有没有更好的方式么?

    这还只是个 200 和 404 的争论,恐怕 200 党肯定也不允许 URL 里面出现 id 参数,不允许使用 put patch delete 吧?
    broadliyn
        87
    broadliyn  
       2019-06-29 18:30:44 +08:00   ❤️ 2
    @sin30
    得了吧你。
    restful 本身只是一种设计风格,不是强制的规范标准,到你这里就变成了 200 党冥顽不灵了?
    现在 graphql 出来,过几年你是不是又要拿着 graphql 来喷 restful 了?

    http 接口怎么定义本身就是自己团队的约定。整天 github 挂嘴,是要把 github 当成神来供奉吗?

    微软 office 团队的页面,https://www.office.com/AAAAAAAAAAAAAAA 类似这种直接 30x 跳转回首页,不用 404。
    苹果未登录用户访问订单详情页返回 303 而非 403 未授权。
    youtube 视频播放页输入一个错误的视频 id 直接返回 200,而且还提示视频无法播放而非视频未找到。
    你挂在嘴上 github api 里,用户个人设置里的一堆 api url 带了 set/update 之类的动词,完全没有照 restful 描述的把动词放在 http 协议里。

    这些大公司都有自己的 api 设计风格,按照你的 restful 标准,微软、苹果、google 都是辣鸡是么?连个 url 设计成 restful 的能力都办不到。

    无知不可怕,非要拿一个标准 /设计风格把自己给圈起来,然后教育别人,跟井底之蛙没什么区别。
    sin30
        88
    sin30  
       2019-07-01 10:59:59 +08:00
    @broadliyn 首先感谢你写这么多。
    sin30
        89
    sin30  
       2019-07-01 11:16:42 +08:00
    @broadliyn 这里确实没有 RESTful 的规范标准,所以我也是说 RESTful 风格或者建议。RESTful 只是建议大家把 HTTP 标准更好的用起来。

    每个公司确实会根据自己的偏好选择某些来实现,规避某些实现,这也是现实存在的,但是你只拿人家做的不好的来说,这就有点偏颇了。

    对于 RESTful 的基本共识大家还是有的,各种开发框架也把这些共识固化下来给大家用了,可以参考 SpringMVC。

    只要是有利于接口表达、使用者方便的好技术、好建议我都支持。

    请看清楚本贴的题目,人家问的是 RESTful API,你可以随便写 http 接口,但请不要说自己是 RESTful。

    另外既然你知道 RESTful 别家公司用的那么烂,有勇气晒一下自己发明的接口规范么?

    看看你不用 Accept 头是怎么做 Content Negotiation 的,不用 Accept-Language 是怎么做多语言国际化的。
    sin30
        90
    sin30  
       2019-07-01 11:23:58 +08:00
    @broadliyn 在你发出自己发明的接口规范之前,我不会对你的回复进行任何无意义的评论。
    sin30
        91
    sin30  
       2019-07-01 11:26:10 +08:00
    @broadliyn 我们可以针对你发明的接口规范来和 RESTful 建议进行一些有意义的讨论,来评判到底谁的设计规范更好用,更规范。
    WilliamYang
        92
    WilliamYang  
       2019-07-01 12:27:37 +08:00
    @broadliyn 我觉得你好像把页面和 api 的路由混为一谈了,在这个主题下,举例不太恰当
    broadliyn
        93
    broadliyn  
       2019-07-01 14:36:25 +08:00
    @WilliamYang 哦?是吗?你把返回页面这么分 html 和 api json 那说明你不懂 restful 了。
    restful 返回的是资源,资源不分 html 还是 json 或者还是其他。
    资源有多种展示格式,html 页面是一种、application/json 也是一种、还有很多 xml、影音视频……。服务端根据客户端 accept 头选择返回需要的格式。

    主题讨论的是 restful url 以及返回的 http status 404 相关的,我为什么不能用普通 html 举例?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3619 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 11:11 · PVG 19:11 · LAX 04:11 · JFK 07:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.